bbm 202 - algorithmsbbm202/spring2017/... · mar. 31, 2016 bbm 202 - algorithms directed graphs...
TRANSCRIPT
Mar. 31, 2016
BBM 202 - ALGORITHMS
DIRECTED GRAPHS
DEPT. OF COMPUTER ENGINEERING
Acknowledgement:ThecourseslidesareadaptedfromtheslidespreparedbyR.SedgewickandK.WayneofPrincetonUniversity.
TODAY ‣ Directed Graphs ‣ Digraph API ‣ Digraph search ‣ Topological sort ‣ Strong components
Digraph. Set of vertices connected pairwise by directed edges.
3
Directed graphs
directedcycle
directed pathfrom 0 to 2
vertex of outdegree 4
and indegree 2
4
Road network
Vertex = intersection; edge = one-way street.Address Holland Tunnel
New York, NY 10013
©2008 Google - Map data ©2008 Sanborn, NAVTEQ™ - Terms of Use
To see all the details that are visible on the screen,use the"Print" link next to the map.
Vertex = political blog; edge = link.
5
Political blogosphere graph
The Political Blogosphere and the 2004 U.S. Election: Divided They Blog, Adamic and Glance, 2005Figure 1: Community structure of political blogs (expanded set), shown using utilizing a GEMlayout [11] in the GUESS[3] visualization and analysis tool. The colors reflect political orientation,red for conservative, and blue for liberal. Orange links go from liberal to conservative, and purpleones from conservative to liberal. The size of each blog reflects the number of other blogs that linkto it.
longer existed, or had moved to a different location. When looking at the front page of a blog we didnot make a distinction between blog references made in blogrolls (blogroll links) from those madein posts (post citations). This had the disadvantage of not differentiating between blogs that wereactively mentioned in a post on that day, from blogroll links that remain static over many weeks [10].Since posts usually contain sparse references to other blogs, and blogrolls usually contain dozens ofblogs, we assumed that the network obtained by crawling the front page of each blog would stronglyreflect blogroll links. 479 blogs had blogrolls through blogrolling.com, while many others simplymaintained a list of links to their favorite blogs. We did not include blogrolls placed on a secondarypage.
We constructed a citation network by identifying whether a URL present on the page of one blogreferences another political blog. We called a link found anywhere on a blog’s page, a “page link” todistinguish it from a “post citation”, a link to another blog that occurs strictly within a post. Figure 1shows the unmistakable division between the liberal and conservative political (blogo)spheres. Infact, 91% of the links originating within either the conservative or liberal communities stay withinthat community. An effect that may not be as apparent from the visualization is that even thoughwe started with a balanced set of blogs, conservative blogs show a greater tendency to link. 84%of conservative blogs link to at least one other blog, and 82% receive a link. In contrast, 74% ofliberal blogs link to another blog, while only 67% are linked to by another blog. So overall, we see aslightly higher tendency for conservative blogs to link. Liberal blogs linked to 13.6 blogs on average,while conservative blogs linked to an average of 15.1, and this difference is almost entirely due tothe higher proportion of liberal blogs with no links at all.
Although liberal blogs may not link as generously on average, the most popular liberal blogs,Daily Kos and Eschaton (atrios.blogspot.com), had 338 and 264 links from our single-day snapshot
4
Vertex = bank; edge = overnight loan.
6
Overnight interbank loan graph
The Topology of the Federal Funds Market, Bech and Atalay, 2008
GSCC
GWCC
Tendril
DC
GOUTGIN
!"#$%& '( !&)&%*+ ,$-). -&/01%2 ,1% 3&4/&56&% 7'8 799:; <=>> ? #"*-/ 0&*2+@ A1--&A/&) A1541-&-/8B> ? )".A1--&A/&) A1541-&-/8 <3>> ? #"*-/ ./%1-#+@ A1--&A/&) A1541-&-/8 <CD ? #"*-/ "-EA1541-&-/8<FGH ? #"*-/ 1$/E A1541-&-/; F- /I". )*@ /I&%& 0&%& JK -1)&. "- /I& <3>>8 L9L -1)&. "- /I& <CD8 :K-1)&. "- <FGH8 J9 -1)&. "- /I& /&-)%"+. *-) 7 -1)&. "- * )".A1--&A/&) A1541-&-/;
!"#$%&%'$( HI& -1)&. 1, * -&/01%2 A*- 6& 4*%/"/"1-&) "-/1 * A1++&A/"1- 1, )".M1"-/ .&/. A*++&) )".A1--&A/&)A1541-&-/.8 !!!" # "!!!!!"; HI& -1)&. 0"/I"- &*AI )".A1--&A/&) A1541-&-/ )1 -1/ I*N& +"-2. /1 1% ,%15-1)&. "- *-@ 1/I&% A1541-&-/8 ";&;8 #!"# $"# !$# "" $ " $ !!!!" % $ $ !!!!!"& # ' ", % (# %!; HI& A1541-&-/0"/I /I& +*%#&./ -$56&% 1, -1)&. ". %&,&%%&) /1 *. /I& )%*$& +"*,-. /'$$"/&"0 /'12'$"$& O<=>>P; C- 1/I&%01%).8 /I& <=>> ". /I& +*%#&./ A1541-&-/ 1, /I& -&/01%2 "- 0I"AI *++ -1)&. A1--&A/ /1 &*AI 1/I&% N"*$-)"%&A/&) 4*/I.; HI& %&5*"-"-# )".A1--&A/&) A1541-&-/. OB>.P *%& .5*++&% A1541-&-/. ,1% 0I"AI /I&.*5& ". /%$&; C- &54"%"A*+ ./$)"&. /I& <=>> ". 1,/&- ,1$-) /1 6& .&N&%*+ 1%)&%. 1, 5*#-"/$)& +*%#&% /I*-*-@ 1, /I& B>. O.&& Q%1)&% "& *-3 O7999PP;
HI& <=>> A1-."./. 1, * )%*$& 4&5'$)-. /'$$"/&"0 /'12'$"$& O<3>>P8 * )%*$& '6&7/'12'$"$& O<FGHP8* )%*$& %$7/'12'$"$& O<CDP *-) &"$05%-4 O.&& !"#$%& 'P; HI& <3>> A154%".&. *++ -1)&. /I*/ A*- %&*AI &N&%@1/I&% -1)& "- /I& <3>> /I%1$#I * )"%&A/&) 4*/I; R -1)& ". "- /I& <FGH ", "/ I*. * 4*/I ,%15 /I& <3>>6$/ -1/ /1 /I& <3>>; C- A1-/%*./8 * -1)& ". "- /I& <CD ", "/ I*. * 4*/I /1 /I& <3>> 6$/ -1/ ,%15 "/; R-1)& ". "- * /&-)%"+ ", "/ )1&. -1/ %&.")& 1- * )"%&A/&) 4*/I /1 1% ,%15 /I& <3>>;S9
!%4/644%'$( C- /I& -&/01%2 1, 4*@5&-/. .&-/ 1N&% !&)0"%& *-*+@T&) 6@ 31%*5U2" "& *-3 O799:P8 /I& <3>>". /I& +*%#&./ A1541-&-/; F- *N&%*#&8 *+51./ %&' 1, /I& -1)&. "- /I*/ -&/01%2 6&+1-# /1 /I& <3>>; C-A1-/%*./8 /I& <3>> ". 5$AI .5*++&% ,1% /I& ,&)&%*+ ,$-). -&/01%2; C- 799:8 1-+@ (&' ) (' 1, /I& -1)&.6&+1-# /1 /I". A1541-&-/; Q@ ,*% /I& +*%#&./ A1541-&-/ ". /I& <CD; C- 799:8 )%' ) )' 1, /I& -1)&. 0&%&"- /I". A1541-&-/; HI& <FGH A1-/*"-&) (*' ) +' 1, *++ -1)&. 4&% )*@8 0I"+& /I&%& 0&%& (+' ) ,' 1,/I& -1)&. +1A*/&) "- /I& /&-)%"+.;SS V&.. /I*- -' ) (' 1, /I& -1)&. 0&%& "- /I& %&5*"-"-# )".A1--&A/&)A1541-&-/. O.&& H*6+& JP;
S9HI& /&-)%"+. 5*@ *+.1 6& )"W&%&-/"*/&) "-/1 /I%&& .$6A1541-&-/.( * .&/ 1, -1)&. /I*/ *%& 1- * 4*/I &5*-*/"-# ,%15 <CD8 *.&/ 1, -1)&. /I*/ *%& 1- * 4*/I +&*)"-# /1 <FGH8 *-) * .&/ 1, -1)&. /I*/ *%& 1- * 4*/I /I*/ 6&#"-. "- <CD *-) &-). "- <FGH;
SS!!"# 1, -1)&. 0&%& "- X,%15E<CDY /&-)%"+.8 $!%# 1, -1)&. 0&%& "- /I& X/1E<FGHY /&-)%"+. *-) "!&# 1, -1)&. 0&%& "-X/$6&.Y ,%15 <CD /1 <FGH;
S7
Vertex = variable; edge = logical implication.
7
Implication graph
~x0
~x3
~x1~x5
x6
x5
~x6
~x4
~x2
x2
x4
x1
x3
x0
if x5 is true,
then x0 is true
Vertex = logical gate; edge = wire.
8
Combinational circuit
Vertex = synset; edge = hypernym relationship.
9
WordNet graph
http://wordnet.princeton.edu
event
happening occurrence occurrent natural_event
change alteration modification
damage harm ..impairment transition
leap jump saltation jump leap
act human_action human_activity
group_action
forfeit forfeiture sacrifice action
change
resistance opposition transgression
demotion variation
motion movement move
locomotion travel
run running
dash sprint
descent
jump parachuting
increase
miracle
miracle
10
Digraph applications
digraph vertex directed edge
transportation street intersection one-way street
web web page hyperlink
food web species predator-prey relationship
WordNet synset hypernym
scheduling task precedence constraint
financial bank transaction
cell phone person placed call
infectious disease person infection
game board position legal move
citation journal article citation
object graph object pointer
inheritance hierarchy class inherits from
control flow code block jump
11
Some digraph problems
Path. Is there a directed path from s to t ?Shortest path. What is the shortest directed path from s to t ?Topological sort. Can you draw the digraph so that all edges point upwards?Strong connectivity. Is there a directed path between all pairs of vertices?Transitive closure. For which vertices v and w is there a path from v to w ?PageRank. What is the importance of a web page?
s
t
DIRECTED GRAPHS
‣ Digraph API ‣ Digraph search ‣ Topological sort ‣ Strong components
13
Digraph API
public class Digraph
Digraph(int V) create an empty digraph with V vertices
Digraph(In in) create a digraph from input stream
void addEdge(int v, int w) add a directed edge v→w
Iterable<Integer> adj(int v) vertices pointing from v
int V() number of vertices
int E() number of edges
Digraph reverse() reverse of this digraph
String toString() string representation
In in = new In(args[0]); Digraph G = new Digraph(in);
for (int v = 0; v < G.V(); v++) for (int w : G.adj(v)) StdOut.println(v + "->" + w);
read digraph from
input stream
print out each
edge (once)
14
Digraph API
In in = new In(args[0]); Digraph G = new Digraph(in);
for (int v = 0; v < G.V(); v++) for (int w : G.adj(v)) StdOut.println(v + "->" + w);
% java Digraph tinyDG.txt 0->5 0->1 2->0 2->3 3->5 3->2 4->3 4->2 5->4 ⋮ 11->4 11->12 12-9
read digraph from
input stream
print out each
edge (once)
adj[]0
1
2
3
4
5
6
7
8
9
10
11
12
5 2
3 2
0 3
5 1
6
0
11 10
6 9
4 12
4
12
9
9 4 8
1322 4 2 2 3 3 2 6 0 0 1 2 011 1212 9 9 10 9 11 7 910 1211 4 4 3 3 5 6 8 8 6 5 4 0 5 6 4 6 9 7 6
tinyDG.txtV
E
⋮
Maintain vertex-indexed array of lists.
adj[]0
1
2
3
4
5
6
7
8
9
10
11
12
5 2
3 2
0 3
5 1
6
0
11 10
6 9
4 12
4
12
9
9 4 8
1322 4 2 2 3 3 2 6 0 0 1 2 011 1212 9 9 10 9 11 7 910 1211 4 4 3 3 5 6 8 8 6 5 4 0 5 6 4 6 9 7 6
tinyDG.txtV
E
15
Adjacency-lists digraph representation
adj[]0
1
2
3
4
5
6
7
8
9
10
11
12
5 2
3 2
0 3
5 1
6
0
11 10
6 9
4 12
4
12
9
9 4 8
1322 4 2 2 3 3 2 6 0 0 1 2 011 1212 9 9 10 9 11 7 910 1211 4 4 3 3 5 6 8 8 6 5 4 0 5 6 4 6 9 7 6
tinyDG.txtV
E
16
Adjacency-lists graph representation: Java implementation
public class Graph { private final int V; private final Bag<Integer>[] adj;
public Graph(int V) { this.V = V; adj = (Bag<Integer>[]) new Bag[V]; for (int v = 0; v < V; v++) adj[v] = new Bag<Integer>(); }
public void addEdge(int v, int w) { adj[v].add(w); adj[w].add(v); }
public Iterable<Integer> adj(int v) { return adj[v]; } }
adjacency lists
create empty graphwith V vertices
iterator for vertices
adjacent to v
add edge v–w
17
Adjacency-lists digraph representation: Java implementation
public class Digraph { private final int V; private final Bag<Integer>[] adj;
public Digraph(int V) { this.V = V; adj = (Bag<Integer>[]) new Bag[V]; for (int v = 0; v < V; v++) adj[v] = new Bag<Integer>(); }
public void addEdge(int v, int w) { adj[v].add(w);
}
public Iterable<Integer> adj(int v) { return adj[v]; } }
adjacency lists
create empty digraphwith V vertices
add edge v→w
iterator for vertices
pointing from v
In practice. Use adjacency-lists representation.• Algorithms based on iterating over vertices pointing from v.
• Real-world digraphs tend to be sparse.
18
Digraph representations
representation spaceinsert edge from v to w
edge from
v to w?
iterate over vertices
pointing from v?
list of edges E 1 E E
adjacency matrix V 2 1 † 1 V
adjacency lists E + V 1 outdegree(v) outdegree(v)
huge number of vertices,small average vertex degree
† disallows parallel edges
DIRECTED GRAPHS
‣ Digraph API ‣ Digraph search ‣ Topological sort ‣ Strong components
20
Reachability
Problem. Find all vertices reachable from s along a directed path.
s
Same method as for undirected graphs.• Every undirected graph is a digraph (with edges in both directions).
• DFS is a digraph algorithm.
21
Depth-first search in digraphs
Mark v as visited.
Recursively visit all unmarked
vertices w pointing from v.
DFS (to visit a vertex v)
adj[]0
1
2
3
4
5
6
7
8
9
10
11
12
5 2
3 2
0 3
5 1
6
0
11 10
6 9
4 12
4
12
9
9 4 8
1322 4 2 2 3 3 2 6 0 0 1 2 011 1212 9 9 10 9 11 7 910 1211 4 4 3 3 5 6 8 8 6 5 4 0 5 6 4 6 9 7 6
tinyDG.txtV
E
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
22
a directed graph
4→2
2→3
3→2
6→0
0→1
2→0
11→12
12→9
9→10
9→11
8→9
10→12
11→4
4→3
3→5
6→8
8→6
5→4
0→5
6→4
6→9
7→6
1
4
9
2
5
3
0
1211
10
8 76
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
23
a directed graph
1
4
9
2
5
3
0
1211
10
8 76 0
1
2
3
4
5
6
7
8
9
10
11
12
marked[]v
F
F
F
F
F
F
F
F
F
F
F
F
F
–
–
–
–
–
–
–
–
–
–
–
–
–
edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
24
visit 0: check 5 and check 1
1
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
marked[]v
T
F
F
F
F
F
F
F
F
F
F
F
F
8 76 –
–
–
–
–
–
–
–
–
–
–
–
–
edgeTo[]
T
F
F
F
F
T
F
F
F
F
F
F
F
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
25
visit 5: check 4
1
4
9
2
5
3
0
1211
10
8 76 0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
–
–
–
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
T
F
F
F
T
T
F
F
F
F
F
F
F
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
26
visit 4: check 3 and check 2
1
4
9
2
5
3
0
1211
10
8 76 0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
–
–
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
27
visit 3: check 5 and check 2
1
4
9
2
5
3
0
1211
10
8 76 T
F
F
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
–
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
28
visit 3: check 5 and check 2
1
4
9
2
5
3
0
1211
10
8 76 T
F
F
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
–
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
29
visit 2: check 0 and check 3
1
4
9
2
5
3
0
1211
10
8 76 T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
30
visit 2: check 0 and check 3
1
4
9
2
5
3
0
1211
10
8 76 T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
21
4
9
5
3
0
1211
10
Depth-first search
31
done 2
1
4
9
5
3
0
1211
10
8 76
3
2
T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
3
1
4
9
2
5
0
1211
10
Depth-first search
32
done 3
1
4
9
5
0
1211
10
8 76
4
3
T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
33
visit 4: check 3 and check 2
1
4
9
5
0
1211
10
8 76 T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
4
1
9
2
5
3
0
1211
10
Depth-first search
34
done 4
1
9
5
0
1211
10
8 76
5
4
T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
5
1
4
9
2
3
0
1211
10
Depth-first search
35
done 5
1
9
0
1211
10
8 76
5
0
T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
36
visit 0: check 5 and check 1
1
9
0
1211
10
8 76 T
F
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
–
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
37
visit 1
1
9
0
1211
10
8 76 T
T
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
Depth-first search
38
done 1
9
0
1211
10
8 76
1
0
T
T
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
8 76
Depth-first search
39
done 0
9
0
1211
10
T
T
T
T
T
T
F
F
F
F
F
F
F
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
3
4
5
0
–
–
–
–
–
–
–
marked[]v edgeTo[]
T
T
T
T
T
T
F
F
F
F
F
F
F
marked[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
1
4
9
2
5
3
0
1211
10
8 76
Depth-first search
40
done
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
3
4
5
0
–
–
–
–
–
–
–
v edgeTo[]
To visit a vertex v :• Mark vertex v as visited.
• Recursively visit all unmarked vertices pointing from v.
T
T
T
T
T
T
F
F
F
F
F
F
F
marked[]
1
9
2
5
3
0
1211
10
8 76
Depth-first search
41
reachable from 0
reachable
from vertex 0
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
3
4
5
0
–
–
–
–
–
–
–
v edgeTo[]
4
Recall code for undirected graphs.
public class DepthFirstSearch { private boolean[] marked;
public DepthFirstSearch(Graph G, int s) { marked = new boolean[G.V()]; dfs(G, s); }
private void dfs(Graph G, int v) { marked[v] = true; for (int w : G.adj(v)) if (!marked[w]) dfs(G, w); }
public boolean visited(int v) { return marked[v]; } }
42
Depth-first search (in undirected graphs)
true if path to s
constructor marks
vertices connected to s
recursive DFS does the work
client can ask whether any
vertex is connected to s
Code for directed graphs identical to undirected one. [substitute Digraph for Graph]
public class DirectedDFS { private boolean[] marked;
public DirectedDFS(Digraph G, int s) { marked = new boolean[G.V()]; dfs(G, s); }
private void dfs(Digraph G, int v) { marked[v] = true; for (int w : G.adj(v)) if (!marked[w]) dfs(G, w); }
public boolean visited(int v) { return marked[v]; } }
43
Depth-first search (in directed graphs)
true if path from s
constructor marks vertices
reachable from s
recursive DFS does the work
client can ask whether any
vertex is reachable from s
44
Reachability application: program control-flow analysis
Every program is a digraph.• Vertex = basic block of instructions (straight-line program).
• Edge = jump.
Dead-code elimination. Find (and remove) unreachable code. Infinite-loop detection. Determine whether exit is unreachable.
Every data structure is a digraph.• Vertex = object.
• Edge = reference.
Roots. Objects known to be directly accessible by program (e.g., stack).Reachable objects. Objects indirectly accessible by program(starting at a root and following a chain of pointers).
45
Reachability application: mark-sweep garbage collector
roo
ts
46
Reachability application: mark-sweep garbage collector
Mark-sweep algorithm. [McCarthy, 1960]• Mark: mark all reachable objects.
• Sweep: if object is unmarked, it is garbage (so add to free list).
Memory cost. Uses 1 extra mark bit per object (plus DFS stack).
roo
ts
DFS enables direct solution of simple digraph problems.• Reachability.
• Path finding.
• Topological sort.
• Directed cycle detection.
Basis for solving difficult digraph problems.• 2-satisfiability.
• Directed Euler path.
• Strongly-connected components.
47
Depth-first search in digraphs summary
✓
SIAM J. COMPUT.Vol. 1, No. 2, June 1972
DEPTH-FIRST SEARCH AND LINEAR GRAPH ALGORITHMS*
ROBERT TARJAN"
Abstract. The value of depth-first search or "bacltracking" as a technique for solving problems isillustrated by two examples. An improved version of an algorithm for finding the strongly connectedcomponents of a directed graph and ar algorithm for finding the biconnected components of an un-direct graph are presented. The space and time requirements of both algorithms are bounded byk1V + k2E d- k for some constants kl, k2, and ka, where Vis the number of vertices and E is the numberof edges of the graph being examined.
Key words. Algorithm, backtracking, biconnectivity, connectivity, depth-first, graph, search,spanning tree, strong-connectivity.
1. Introduction. Consider a graph G, consisting of a set of vertices U and aset of edges g. The graph may either be directed (the edges are ordered pairs (v, w)of vertices; v is the tail and w is the head of the edge) or undirected (the edges areunordered pairs of vertices, also represented as (v, w)). Graphs form a suitableabstraction for problems in many areas; chemistry, electrical engineering, andsociology, for example. Thus it is important to have the most economical algo-rithms for answering graph-theoretical questions.
In studying graph algorithms we cannot avoid at least a few definitions.These definitions are more-or-less standard in the literature. (See Harary [3],for instance.) If G (, g) is a graph, a path p’v w in G is a sequence of verticesand edges leading from v to w. A path is simple if all its vertices are distinct. A pathp’v v is called a closed path. A closed path p’v v is a cycle if all its edges aredistinct and the only vertex to occur twice in p is v, which occurs exactly twice.Two cycles which are cyclic permutations of each other are considered to be thesame cycle. The undirected version of a directed graph is the graph formed byconverting each edge of the directed graph into an undirected edge and removingduplicate edges. An undirected graph is connected if there is a path between everypair of vertices.
A (directed rooted) tree T is a directed graph whose undirected version isconnected, having one vertex which is the head of no edges (called the root),and such that all vertices except the root are the head of exactly one edge. Therelation "(v, w) is an edge of T" is denoted by v- w. The relation "There is apath from v to w in T" is denoted by v w. If v - w, v is the father ofw and w is ason of v. If v w, v is an ancestor ofw and w is a descendant of v. Every vertex is anancestor and a descendant of itself. If v is a vertex in a tree T, T is the subtree of Thaving as vertices all the descendants of v in T. If G is a directed graph, a tree Tis a spanning tree of G if T is a subgraph of G and T contains all the vertices of G.
If R and S are binary relations, R* is the transitive closure of R, R-1 is theinverse of R, and
RS {(u, w)lZlv((u, v) R & (v, w) e S)}.
* Received by the editors August 30, 1971, and in revised form March 9, 1972.
" Department of Computer Science, Cornell University, Ithaca, New York 14850. This researchwas supported by the Hertz Foundation and the National Science Foundation under Grant GJ-992.
146
Same method as for undirected graphs.• Every undirected graph is a digraph (with edges in both directions).
• BFS is a digraph algorithm.
Proposition. BFS computes shortest paths (fewest number of edges) from s to all other vertices n a digraph in time proportional to E+V.
48
Breadth-first search in digraphs
Is w reachable from v in this digraph?
v
w
s
Put s onto a FIFO queue, and mark s as visited.Repeat until the queue is empty:
- remove the least recently added vertex v
- for each unmarked vertex pointing from v: add to queue and mark as visited.
BFS (from source vertex s)
Multiple-source shortest paths. Given a digraph and a set of source vertices, find shortest path from any vertex in the set to each other vertex.Ex. S={ 1, 7, 10 }. • Shortest path to 4 is 7→6→4.
• Shortest path to 5 is 7→6→0→5.
• Shortest path to 12 is 10→12.
Q. How to implement multi-source constructor?A. Use BFS, but initialize by enqueuing all source vertices.
49
Multiple-source shortest paths
adj[]0
1
2
3
4
5
6
7
8
9
10
11
12
5 2
3 2
0 3
5 1
6
0
11 10
6 9
4 12
4
12
9
9 4 8
1322 4 2 2 3 3 2 6 0 0 1 2 011 1212 9 9 10 9 11 7 910 1211 4 4 3 3 5 6 8 8 6 5 4 0 5 6 4 6 9 7 6
tinyDG.txtV
E
50
Breadth-first search in digraphs application: web crawler
Goal. Crawl web, starting from some root web page, say www.princeton.edu.Solution. BFS with implicit graph.BFS.• Choose root web page as source s.
• Maintain a Queue of websites to explore.
• Maintain a SET of discovered websites.
• Dequeue the next website and enqueue websites to which it links (provided you haven't done so before).
Q. Why not use DFS?
18
31
6
42 13
28
32
49
22
45
1 14
40
48
7
44
10
4129
0
39
11
9
12
3026
21
46
5
24
37
43
35
47
38
23
16
36
4
3 17
27
20
34
15
2
19 33
25
8
How many strong components are there in this digraph?
51
Bare-bones web crawler: Java implementation Queue<String> queue = new Queue<String>(); SET<String> discovered = new SET<String>();
String root = "http://www.princeton.edu"; queue.enqueue(root); discovered.add(root);
while (!queue.isEmpty()) { String v = queue.dequeue(); StdOut.println(v); In in = new In(v); String input = in.readAll();
String regexp = "http://(\\w+\\.)*(\\w+)"; Pattern pattern = Pattern.compile(regexp); Matcher matcher = pattern.matcher(input); while (matcher.find()) { String w = matcher.group(); if (!discovered.contains(w)) { discovered.add(w); queue.enqueue(w); } } }
read in raw html from next
website in queue
use regular expression to find all URLsin website of form http://xxx.yyy.zzz
[crude pattern misses relative URLs]
if undiscovered, mark it as discovered and put on queue
start crawling from root website
queue of websites to crawlset of discovered websites
DIRECTED GRAPHS
‣ Digraph API ‣ Digraph search ‣ Topological sort ‣ Strong components
Goal. Given a set of tasks to be completed with precedence constraints, in which order should we schedule the tasks?
Digraph model. vertex = task; edge = precedence constraint.
53
Precedence scheduling
tasks precedence constraint graph
0
1
4
52
6
3
feasible schedule
0. Algorithms
1. Complexity Theory
2. Artificial Intelligence
3. Intro to CS
4. Cryptography
5. Scientific Computing
6. Advanced Programming
54
Topological sort
DAG. Directed acyclic graph.
Topological sort. Redraw DAG so all edges point upwards.
Solution. DFS. What else?topological order
directed edges DAG
0→5 0→2 0→1 3→6 3→5 3→4 5→4 6→4 6→0 3→2 1→4
0
1
4
52
6
3
• Run depth-first search.
• Return vertices in reverse postorder.
0
1
4
52
6
3
Topological sort algorithm
55
a directed acyclic graph
0→5 0→2 0→1 3→6 3→5 3→4 5→4 6→4 6→0 3→2 1→4
1
4
52
6
3
0
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
56
0
1
4
52
6
3
0
4
52
6
3
visit 0: check 1, check 2, and check 5
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
57
0
1
4
52
6
3
0
1
4
52
6
3
visit 1: check 4
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
58
0
1
4
52
6
3
0
1
4
52
6
3
visit 4
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
59
4
0
1
4
52
6
3
0
152
6
3
4 done
4
postorder
1
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
60
4
0
1
4
52
6
3
0
152
6
3
visit 1
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
61
4 1
0
1
4
52
6
3
0
52
6
3
1 done
1
postorder
0
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
62
4 1
0
1
4
52
6
3
0
52
6
3
visit 0: check 1, check 2, and check 5
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
63
4 1
0
1
4
52
6
3
0
52
6
3
visit 2
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
64
4 1 2
0
1
4
52
6
3
0
5
6
3
2 done
2
postorder
0
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
65
4 1 2
0
1
4
52
6
3
0
5
6
3
visit 0: check 1, check 2, and check 5
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
66
4 1 2
0
1
4
52
6
3
0
5
6
3
visit 5: check 2
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
67
4 1 2
0
1
4
52
6
3
0
5
6
3
visit 5
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
68
4 1 2 5
0
1
4
52
6
3
0
6
3
5 done
5
postorder
0
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
69
4 1 2 5
0
1
4
52
6
3
0
6
3
visit 0
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
70
4 1 2 5 0
0
1
4
52
6
3
6
3
0 done
0
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
71
4 1 2 5 0
0
1
4
52
6
3
6
3
check 1
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
72
4 1 2 5 0
0
1
4
52
6
3
6
3
check 2
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
73
4 1 2 5 0
0
1
4
52
6
3
6
3
visit 3: check 2, check 4, check 5, and check 6
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
74
4 1 2 5 0
0
1
4
52
6
3
6
3
visit 3: check 2, check 4, check 5, and check 6
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
75
4 1 2 5 0
0
1
4
52
6
3
6
3
visit 3: check 2, check 4, check 5, and check 6
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
76
4 1 2 5 0
0
1
4
52
6
3
6
3
visit 3: check 2, check 4, check 5, and check 6
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
77
4 1 2 5 0
0
1
4
52
6
3
6
3
visit 6: check 0 and check 4
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
78
4 1 2 5 0
0
1
4
52
6
3
6
3
visit 6: check 0 and check 4
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
6
Topological sort algorithm
79
4 1 2 5 0 6
0
1
4
52
33
6 done
postorder
3
6
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
80
4 1 2 5 0 6
0
1
4
52
6
33
visit 3
postorder
33
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
81
4 1 2 5 0 6 3
0
1
4
52
6
3 done
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
82
4 1 2 5 0 6 3
0
1
4
52
6
3
check 4
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
83
4 1 2 5 0 6 3
0
1
4
52
6
3
check 5
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
84
4 1 2 5 0 6 3
0
1
4
52
6
3
check 6
postorder
• Run depth-first search.
• Return vertices in reverse postorder.
Topological sort algorithm
85
4 1 2 5 0 6 3
postorder
done
0
1
4
52
6
3
0
1
4
52
6
3
3 6 0 5 2 1 4
topological order
86
Depth-first search order
public class DepthFirstOrder { private boolean[] marked; private Stack<Integer> reversePost;
public DepthFirstOrder(Digraph G) { reversePost = new Stack<Integer>(); marked = new boolean[G.V()]; for (int v = 0; v < G.V(); v++) if (!marked[v]) dfs(G, v); }
private void dfs(Digraph G, int v) { marked[v] = true; for (int w : G.adj(v)) if (!marked[w]) dfs(G, w); reversePost.push(v); } public Iterable<Integer> reversePost() { return reversePost; } }
returns all vertices in
“reverse DFS postorder”
Proposition. Reverse DFS postorder of a DAG is a topological order.Pf. Consider any edge v→w. When dfs(v) is called:
• Case 1: dfs(w) has already been called and returned. Thus, w was done before v.
• Case 2: dfs(w) has not yet been called. dfs(w) will get called directly or indirectly by dfs(v) and will finish before dfs(v). Thus, w will be done before v.
• Case 3: dfs(w) has already been called, but has not yet returned. Can’t happen in a DAG: function call stack containspath from w to v, so v→w would complete a cycle.
dfs(0) dfs(1) dfs(4) 4 done 1 done dfs(2) 2 done dfs(5) check 2 5 done 0 done check 1 check 2 dfs(3) check 2 check 4 check 5 dfs(6) 6 done 3 done check 4 check 5 check 6 done
87
Topological sort in a DAG: correctness proof
all vertices pointing from 3 are done before 3 is done,
so they appear after 3 in topological order
Ex:
case 1
case 2
Proposition. A digraph has a topological order iff no directed cycle.Pf.• If directed cycle, topological order impossible.
• If no directed cycle, DFS-based algorithm finds a topological order.
Goal. Given a digraph, find a directed cycle.Solution. DFS. What else? See textbook.
88
Directed cycle detection
Finding a directed cycle in a digraph
dfs(0) dfs(5) dfs(4) dfs(3) check 5
marked[] edgeTo[] onStack[]0 1 2 3 4 5 ... 0 1 2 3 4 5 ... 0 1 2 3 4 5 ...
1 0 0 0 0 0 - - - - - 0 1 0 0 0 0 0 1 0 0 0 0 1 - - - - 5 0 1 0 0 0 0 1 1 0 0 0 1 1 - - - 4 5 0 1 0 0 0 1 1 1 0 0 1 1 1 - - - 4 5 0 1 0 0 1 1 1
a digraph with a directed cycle
Scheduling. Given a set of tasks to be completed with precedence constraints, in what order should we schedule the tasks?
Remark. A directed cycle implies scheduling problem is infeasible.
89
Directed cycle detection application: precedence scheduling
http://xkcd.com/754
90
Directed cycle detection application: cyclic inheritance
The Java compiler does cycle detection.
public class A extends B { ... }
public class B extends C { ... }
public class C extends A { ... }
% javac A.java A.java:1: cyclic inheritance involving A public class A extends B { } ^ 1 error
Microsoft Excel does cycle detection (and has a circular reference toolbar!)
91
Directed cycle detection application: spreadsheet recalculation
92
Directed cycle detection applications
• Causalities.
• Email loops.
• Compilation units.
• Class inheritance.
• Course prerequisites.
• Deadlocking detection.
• Precedence scheduling.
• Temporal dependencies.
• Pipeline of computing jobs.
• Check for symbolic link loop.
• Evaluate formula in spreadsheet.
DIRECTED GRAPHS
‣ Digraph API ‣ Digraph search ‣ Topological sort ‣ Strong components
Def. Vertices v and w are strongly connected if there is a directed path from v to w and a directed path from w to v.
Key property. Strong connectivity is an equivalence relation:• v is strongly connected to v.
• If v is strongly connected to w, then w is strongly connected to v.
• If v is strongly connected to w and w to x, then v is strongly connected to x.
Def. A strong component is a maximal subset of strongly-connected vertices.
Strongly-connected components
94
A digraph and its strong components
Examples of strongly-connected digraphs
95
public int connected(int v, int w) { return cc[v] == cc[w]; }
Connected components vs. strongly-connected components
96
0 1 2 3 4 5 6 7 8 9 10 11 12 cc[] 0 0 0 0 0 0 1 1 1 2 2 2 2
• v and w are connected if there isa path between v and w
•v and w are strongly connected if there is a directed
path from v to w and a directed path from w to v
0 1 2 3 4 5 6 7 8 9 10 11 12 scc[] 1 0 1 1 1 1 3 4 3 2 2 2 2
constant-time client connectivity query constant-time client strong-connectivity query
•3 connected components •5 strongly-connected components
connected component id (easy to compute with DFS) strongly-connected component id (how to compute?)
A digraph and its strong componentsA graph and its connected components
public int stronglyConnected(int v, int w) { return scc[v] == scc[w]; }
A digraph and its strong components
97
Strong component application: ecological food webs
Food web graph. Vertex = species; edge = from producer to consumer.
Strong component. Subset of species with common energy flow.
http://www.twingroves.district96.k12.il.us/Wetlands/Salamander/SalGraphics/salfoodweb.gif
98
Strong component application: software modules
Software module dependency graph.• Vertex = software module.
• Edge: from module to dependency.
Strong component. Subset of mutually interacting modules. Approach 1. Package strong components together.Approach 2. Use to improve design!
Internet ExplorerFirefox
Strong components algorithms: brief history
1960s: Core OR problem.• Widely studied; some practical algorithms.
• Complexity not understood.
1972: linear-time DFS algorithm (Tarjan).• Classic algorithm.
• Level of difficulty: Algs4++.
• Demonstrated broad applicability and importance of DFS.
1980s: easy two-pass linear-time algorithm (Kosaraju-Sharir).• Forgot notes for lecture; developed algorithm in order to teach it!
• Later found in Russian scientific literature (1972).
1990s: more easy linear-time algorithms.• Gabow: fixed old OR algorithm.
• Cheriyan-Mehlhorn: needed one-pass algorithm for LEDA.
99
A digraph and its strong components
Reverse graph. Strong components in G are same as in GR.Kernel DAG. Contract each strong component into a single vertex.Idea.• Compute topological order (reverse postorder) in kernel DAG.
• Run DFS, considering vertices in reverse topological order.
100
Kosaraju's algorithm: intuition
digraph G and its strong components kernel DAG of G (in reverse topological order)
how to compute?
Kernel DAG in reverse topological order
first vertex is a sink (has no edges pointing from it)
KOSARAJU'S ALGORITHM
‣ DFS in reverse graph ‣ DFS in original graph
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
102
digraph G
1
4
9
2
5
3
0
1211
10
8 76 8 76
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
103
reverse digraph GR
0
1
2
3
4
5
6
7
8
9
10
11
12
marked[v]v
–
–
–
–
–
–
–
–
–
–
–
–
–
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
104
visit 0: check 6 and check 2
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
F
F
F
F
F
F
F
marked[v]v
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
105
visit 6: check 8 and check 7
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
T
F
F
F
F
F
F
marked[v]v
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
106
visit 8: check 6
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
T
F
T
F
F
F
F
marked[v]v
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
107
8 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
T
F
T
F
F
F
F
marked[v]v
8
6
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
7
Kosaraju-Sharir
108
visit 6: check 8 and check 7
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
T
F
T
F
F
F
F
6
marked[v]v
8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
7
Kosaraju-Sharir
109
visit 7
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
T
T
T
F
F
F
F
6
marked[v]v
8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
7
Kosaraju-Sharir
110
7 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
F
F
F
F
T
T
T
F
F
F
F
6
marked[v]v
7 8
6
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
0
1211
10
1
Kosaraju-Sharir
111
6 done
0
1
2
3
4
5
6
7
8
9
10
11
12
6
marked[v]v
6 7 8
T
F
F
F
F
F
T
T
T
F
F
F
F
0
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
112
visit 0: check 6 and check 2
0
1
2
3
4
5
6
7
8
9
10
11
12
0marked[v]v
6 7 8
T
F
F
F
F
F
T
T
T
F
F
F
F
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
113
visit 2: check 4 and check 3
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
F
F
T
T
T
F
F
F
F
0marked[v]v
6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
114
visit 4: check 11, check 6, and check 5
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
F
F
F
F
0
6 7 8
marked[v]v
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
115
visit 11: check 9
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
F
F
T
F
0marked[v]v
6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
116
visit 9: check 12, check 7, and check 6
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
F
T
F
0marked[v]v
6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
117
visit 12: check 11 and check 10
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
F
T
T
0marked[v]v
6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
118
visit 12: check 11 and check 10
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
F
T
T
0marked[v]v
6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
119
visit 10: check 9
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0marked[v]v
6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
1211
10
1
Kosaraju-Sharir
120
10 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0marked[v]v
10 6 7 8
12
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
9
2
5
3
11
1
Kosaraju-Sharir
121
12 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
12
marked[v]v
12 10 6 7 8
9
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
2
5
3
11
1
Kosaraju-Sharir
122
visit 9: check 12, check 7, and check 6
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
9
marked[v]v
12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
2
5
3
11
1
Kosaraju-Sharir
123
visit 9: check 12, check 7, and check 6
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
9
marked[v]v
12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
2
5
3
11
1
Kosaraju-Sharir
124
9 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
9
marked[v]v
9 12 10 6 7 8
11
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1
4
2
5
3
1
Kosaraju-Sharir
125
11 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
11
marked[v]v
11 9 12 10 6 7 8
4
Phase 1. Compute reverse postorder in GR.11 9 12 10 6 7 8
1
4
9
2
5
3
0
1211
10
1
8 76
1 2
5
3
1
Kosaraju-Sharir
126
visit 4: check 11, check 6, and check 5
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
4
marked[v]v
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 2
5
3
1
Kosaraju-Sharir
127
visit 4: check 11, check 6, and check 5
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
F
T
T
T
T
T
T
T
0
4
marked[v]v
11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 2
5
3
1
Kosaraju-Sharir
128
visit 5: check 3 and check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
F
T
T
T
T
T
T
T
T
T
0
4
marked[v]v
11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 2
5
3
1
Kosaraju-Sharir
129
visit 3: check 4 and check 2
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
T
T
T
T
T
T
T
T
T
T
0
4
marked[v]v
11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 2
5
3
1
Kosaraju-Sharir
130
visit 3: check 4 and check 2
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
T
T
T
T
T
T
T
T
T
T
0
4
marked[v]v
11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 2
5
3
1
Kosaraju-Sharir
131
3 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
T
T
T
T
T
T
T
T
T
T
0
4
marked[v]v
3 11 9 12 10 6 7 8
5
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 21
Kosaraju-Sharir
132
visit 5: check 3 and check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
T
F
T
T
T
T
T
T
T
T
T
T
T
0
4
5
marked[v]v
3 11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 21
Kosaraju-Sharir
133
5 done
0
1
2
3
4
5
6
7
8
9
10
11
12
0
4
5
marked[v]v
5 3 11 9 12 10 6 7 8
T
F
T
T
T
T
T
T
T
T
T
T
T
4
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
1 21
Kosaraju-Sharir
134
4 done
0
1
2
3
4
5
6
7
8
9
10
11
12
0
4
marked[v]v
4 5 3 11 9 12 10 6 7 8
T
F
T
T
T
T
T
T
T
T
T
T
T
2
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
11
Kosaraju-Sharir
135
visit 2: check 4 and check 3
0
1
2
3
4
5
6
7
8
9
10
11
12
0
2
marked[v]v
4 5 3 11 9 12 10 6 7 8
T
F
T
T
T
T
T
T
T
T
T
T
T
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
11
Kosaraju-Sharir
136
2 done
0
1
2
3
4
5
6
7
8
9
10
11
12
0
2
marked[v]v
2 4 5 3 11 9 12 10 6 7 8
T
F
T
T
T
T
T
T
T
T
T
T
T
0
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
11
Kosaraju-Sharir
137
0 done
0
1
2
3
4
5
6
7
8
9
10
11
12
0marked[v]v
0 2 4 5 3 11 9 12 10 6 7 8
T
F
T
T
T
T
T
T
T
T
T
T
T
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
11
Kosaraju-Sharir
138
visit 1: check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
T
T
T
T
T
T
T
T
T
T
T
T
T
marked[v]v
0 2 4 5 3 11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
139
1 done
0
1
2
3
4
5
6
7
8
9
10
11
12
T
T
T
T
T
T
T
T
T
T
T
T
T
marked[v]v
1 0 2 4 5 3 11 9 12 10 6 7 8
1
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
140
check 2 3 4 5 6 7 8 9 10 11 12
0
1
2
3
4
5
6
7
8
9
10
11
12
T
T
T
T
T
T
T
T
T
T
T
T
T
marked[v]v
1 0 2 4 5 3 11 9 12 10 6 7 8
Phase 1. Compute reverse postorder in GR.
1
4
9
2
5
3
0
1211
10
1
8 76
Kosaraju-Sharir
141
1 0 2 4 5 3 11 9 12 10 6 7 8
reverse digraph GR
Simple (but mysterious) algorithm for computing strong components.• Run DFS on GR to compute reverse postorder.
• Run DFS on G, considering vertices in order given by first DFS.
142
Kosaraju's algorithm
...
check unmarked vertices in the order 0 1 2 3 4 5 6 7 8 9 10 11 12
dfs(0) dfs(6) dfs(8) check 6 8 done dfs(7) 7 done 6 done dfs(2) dfs(4) dfs(11) dfs(9) dfs(12) check 11 dfs(10) check 9 10 done 12 done check 7 check 6 9 done 11 done check 6 dfs(5) dfs(3) check 4 check 2 3 done check 0 5 done 4 done check 3 2 done0 donedfs(1) check 01 donecheck 2check 3check 4check 5check 6check 7check 8check 9check 10check 11check 12
DFS in reverse digraph GR
reverse postorder for use in second dfs()1 0 2 4 5 3 11 9 12 10 6 7 8
KOSARAJU'S ALGORITHM
‣ DFS in reverse graph ‣ DFS in original graph
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
144
1
4
9
2
5
3
0
1211
10
8 76 8 76 0
1
2
3
4
5
6
7
8
9
10
11
12
scc[v]v
–
–
–
–
–
–
–
–
–
–
–
–
–
original digraph G
1 0 2 4 5 3 11 9 12 10 6 7 8
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
145
1
4
9
2
5
3
0
1211
10
8 76 8 76
visit 1
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
–
–
–
–
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
11
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
146
4
9
2
5
3
0
1211
10
8 76 8 76
1 done
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
–
–
–
–
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
147
1
4
9
2
5
3
0
1211
10
8 76 8 76
strong component: 1
0
1
2
3
4
5
6
7
8
9
10
11
12
–
0
–
–
–
–
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
1
0
–
–
–
–
–
–
–
–
–
–
–
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
148
visit 0: check 5 and check 1
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
1
0
–
–
–
1
–
–
–
–
–
–
–
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
149
visit 5: check 4
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
1
0
–
–
1
1
–
–
–
–
–
–
–
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
150
visit 4: check 3 and check 2
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
1
0
–
1
1
1
–
–
–
–
–
–
–
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
151
visit 3: check 5 and check 2
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
152
visit 3: check 5 and check 2
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
–
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
1
0
1
1
1
1
–
–
–
–
–
–
–
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
153
visit 2: check 0 and check 3
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
154
visit 2: check 0 and check 3
4
9
2
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
22
4
9
5
3
0
1211
10
Kosaraju-Sharir
155
2 done
4
9
5
3
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
3
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
3
4
9
2
5
0
1211
10
Kosaraju-Sharir
156
3 done
4
9
5
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
3
4
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
157
visit 4: check 3 and check 2
4
9
5
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
9
2
5
3
0
1211
10
Kosaraju-Sharir
158
4 done
9
5
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
44
5
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
5
4
9
2
3
0
1211
10
Kosaraju-Sharir
159
5 done
9
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
5
0
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
4
9
2
5
3
0
1211
10
Kosaraju-Sharir
160
visit 0: check 5 and check 1
9
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
8 76
1
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
00
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
1211
10
8 76
Kosaraju-Sharir
161
0 done
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
3
0
1211
10
8 76
Kosaraju-Sharir
162
strong component: 0 2 3 4 5
9
0
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
–
–
5
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
163
check 2
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
164
check 4
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
165
check 5
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
166
check 3
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
–
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
167
visit 11: check 4 and check 12
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
2
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
168
visit 11: check 4 and check 12
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
2
–
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
169
visit 12: check 9
9
1211
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
–
–
2
2
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
170
visit 9: check 11 and check 10
9
12
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
–
2
2
11
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
171
visit 9: check 11 and check 10
9
12
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
–
2
2
11
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
8 76
Kosaraju-Sharir
172
visit 10: check 12
9
12
10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
11
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
10
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
173
10 done
9
12
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
11
9 10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
9
1
4
2
5
3
0
1211
8 76
Kosaraju-Sharir
174
9 done
12
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
11
109
12
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
12
1
4
9
2
5
3
0
11
8 76
Kosaraju-Sharir
175
12 done
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
11
10
11 12
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
1111
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
12
8 76
Kosaraju-Sharir
176
11 done
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
177
strong component: 9 10 11 12
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
11
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
178
check 9
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
179
check 12
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
180
check 10
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
–
–
–
2
2
2
2
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
181
visit 6: check 9, check 4, check 8, and check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
–
2
2
2
2
86 7
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
182
visit 6: check 9, check 4, check 8, and check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
–
2
2
2
2
8 76
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
183
visit 6: check 9, check 4, check 8, and check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
–
2
2
2
2
8 76
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
184
visit 8: check 6
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
3
2
2
2
2
8 76
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
8
1
4
9
2
5
3
0
1211
7
Kosaraju-Sharir
185
8 done
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
3
2
2
2
2
7
10
6 866
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
186
visit 6: check 9, check 4, check 8, and check 0
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
3
2
2
2
2
76
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
187
6 done
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
3
2
2
2
2
7
10
6
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 7
Kosaraju-Sharir
188
strong component: 6 8
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
–
3
2
2
2
2
7
10
6
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
189
visit 7: check 6 and check 9
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
4
3
2
2
2
2
7
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
190
visit 7: check 6 and check 9
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
4
3
2
2
2
2
7
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
191
7 done
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
4
3
2
2
2
2
7
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
8 76
Kosaraju-Sharir
192
strong component: 7
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
4
3
2
2
2
2
7
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
86 7
Kosaraju-Sharir
193
check 8
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
4
3
2
2
2
2
10
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Phase 2. Run DFS in G, visiting unmarked vertices in reverse postorder of GR.
1
4
9
2
5
3
0
1211
10
86 7
Kosaraju-Sharir
194
done
0
1
2
3
4
5
6
7
8
9
10
11
12
1
0
1
1
1
1
3
4
3
2
2
2
2
1 0 2 4 5 3 11 9 12 10 6 7 8
scc[v]v
Simple (but mysterious) algorithm for computing strong components.• Run DFS on GR to compute reverse postorder.
• Run DFS on G, considering vertices in order given by first DFS.
Proposition. Second DFS gives strong components. (!!)
195
Kosaraju's algorithm
dfs(7) check 6 check 97 donecheck 8
check unmarked vertices in the order 1 0 2 4 5 3 11 9 12 10 6 7 8
DFS in original digraph G
dfs(1)1 done
dfs(0) dfs(5) dfs(4) dfs(3) check 5 dfs(2) check 0 check 3 2 done 3 done check 2 4 done 5 done check 10 donecheck 2check 4check 5check 3
dfs(11) check 4 dfs(12) dfs(9) check 11 dfs(10) check 12 10 done 9 done 12 done11 donecheck 9check 12check 10
dfs(6) check 9 check 4 dfs(8) check 6 8 done check 06 done
196
Connected components in an undirected graph (with DFS)
public class CC { private boolean marked[]; private int[] id; private int count;
public CC(Graph G) { marked = new boolean[G.V()]; id = new int[G.V()];
for (int v = 0; v < G.V(); v++) { if (!marked[v]) { dfs(G, v); count++; } } }
private void dfs(Graph G, int v) { marked[v] = true; id[v] = count; for (int w : G.adj(v)) if (!marked[w]) dfs(G, w); }
public boolean connected(int v, int w) { return id[v] == id[w]; } }
197
Strong components in a digraph (with two DFSs)
public class KosarajuSCC { private boolean marked[]; private int[] id; private int count;
public KosarajuSCC(Digraph G) { marked = new boolean[G.V()]; id = new int[G.V()]; DepthFirstOrder dfs = new DepthFirstOrder(G.reverse()); for (int v : dfs.reversePost()) { if (!marked[v]) { dfs(G, v); count++; } } }
private void dfs(Digraph G, int v) { marked[v] = true; id[v] = count; for (int w : G.adj(v)) if (!marked[w]) dfs(G, w); }
public boolean stronglyConnected(int v, int w) { return id[v] == id[w]; } }
Digraph-processing summary: algorithms of the day
198
single-source reachability
DFS
topological sort (DAG)
DFS
strong components
Kosaraju DFS (twice)
06
4
21
5
3
7
12
109
11
8