<<

Data Structures in Java

Lecture 19: Applications of DFS

11/30/2015

Daniel Bauer

1 Contents

• Applications of DFS

• Euler Circuits

• Biconnectivity in Undirected Graphs.

• Finding Strongly Connected Components for Directed Graphs.

2 Contents

• Applications of DFS

• Euler Circuits

• Biconnectivity in Undirected Graphs.

• Finding Strongly Connected Components for Directed Graphs.

3 Draw this Figure Without lifting your pen off the paper.

4 Euler Paths • An Euler is a path through an undirected graph that visits every edge exactly once.

5 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

6 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

7 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

8 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

9 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

10 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

11 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

12 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

13 Euler Paths • An Euler Path is a path through an undirected graph that visits every edge exactly once.

This graph does not have an Euler Path.

14 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

This graph does NOT have an Euler Circuit 15 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

16 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

17 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

18 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

19 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

20 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

21 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

22 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

23 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

24 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

25 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

26 Euler Circuit

• An Euler Circuit is an Euler path that begins and ends at the same node.

This graph does not have an Euler Path.

27 Necessary Condition for Euler Circuits • Observation: • Once we enter v, we need another edge to leave it. • If v has an odd number of edges, the last time we enter v, we will be stuck!

3

28 Necessary Condition for Euler Circuits • Observation: • Once we enter v, we need another edge to leave it. • If v has an odd number of edges, the last time we enter v, we will be stuck!

2

29 Necessary Condition for Euler Circuits • Observation: • Once we enter v, we need another edge to leave it. • If v has an odd number of edges, the last time we enter v, we will be stuck!

1

30 Necessary Condition for Euler Circuits • Observation: • Once we enter v, we need another edge to leave it. • If v has an odd number of edges, the last time we enter v, we will be stuck! • For an Euler Circuit to exist in a graph, all vertices need to have even (even number of edges).

0

31 Necessary Condition for Euler Paths • For an Euler Path to exist in a graph, exactly 0 or 2 vertices must have odd degree. • Start with one of the odd vertices.

• End in the other one.

3

3 32 Necessary Condition for Euler Paths • For an Euler Path to exist in a graph, exactly 0 or 2 vertices must have odd degree. • Start with one of the odd vertices.

• End in the other one.

3

3 33 Conditions for Euler Paths and Circuits • For an Euler Circuit to exist in a graph, all vertices need to have even degree (even number of edges). • For an Euler Path to exist in a graph, exactly 0 or 2 vertices need to have odd degree.

• These conditions are also sufficient! (i.e. every graph that contains only vertices of even degree has an Euler circuit). (Hierholzer, 1873 )

34 Seven Bridges of Königsberg Leonhard Euler, 1735

The city of Königsberg in Prussia (now Kaliningrad, Russia) was set on both sides of the Pregel River, and included two large islands which were connected to each other and the mainland by seven bridges.

Euler’s Problem: Find a walk through the city that crosses every exactly once!

Source:35 Wikipedia Seven Bridges of Königsberg Leonhard Euler, 1735

36 Seven Bridges of Königsberg Leonhard Euler, 1735

3

5 3

3

There is no Euler Path in this graph.

37 Finding Euler Circuits

• Start with any s. First, using DFS find any circuit starting and ending in s. Mark all edges on the circuit as visited.

• Because all vertices have even degree, we are guaranteed to not get stuck before we arrive at s again.

• While there are still edges in the graph that are not market visited:

• Find the first vertex v on the circuit that has unvisited edges. • Find a circuit starting in v and splice this path into the first circuit

38 Finding Euler Circuits

1 2 3 2 4 2

4 4 7 5 4 4 6 4

8 9 10 2 2 4

39 Finding Euler Circuits

1 2 3 1 3 2

4 4 7 5 4 4 6 4

8 9 10 2 2 4

40 Finding Euler Circuits

1 2 3 1 2 2

4 3 7 5 4 4 6 4

8 9 10 2 2 4

41 Finding Euler Circuits

1 2 3 1 2 2

4 2 7 5 4 4 6 3

8 9 10 2 2 4

42 Finding Euler Circuits

1 2 3 1 2 2

4 2 7 5 4 3 6 2

8 9 10 2 2 4

43 Finding Euler Circuits

1 2 3 0 2 2

4 2 7 5 4 2 6 2

8 9 10 2 2 4

1 2 4 6 5 1 44 Finding Euler Circuits

1 2 3 0 2 2

4 2 7 5 4 2 6 2

8 9 10 2 2 4

1 2 4 6 5 1 45 Finding Euler Circuits

1 2 3 0 0 0

4 2 7 5 2 2 7 6 10 3 2 2 6 0

8 9 10 2 2 2

1 2 4 6 5 1 46 Finding Euler Circuits

1 2 3 0 0 0

4 2 7 5 2 2 7 6 10 3 2 2 6 0

8 9 10 2 2 2

1 4 6 5 1 47 Finding Euler Circuits

1 2 3 0 0 0

4 0

7 5 0 7 4 5 8 9 10 7 0 6 0

8 9 10 0 0 0 1 2 7 6 10 3 2 4 6 5 1 48 Finding Euler Circuits

1 2 3 0 0 0

4 0

7 5 0 7 4 5 8 9 10 7 0 6 0

8 9 10 0 0 0

1 2 6 10 3 2 4 6 5 1 49 Hamiltonian

• A Hamiltonian Path is a path through an undirected graph that visits every vertex exactly once (except that the first and last vertex may be the same).

• A Hamiltonian Cycle is a Hamiltonian Path that starts and ends in the same node.

50 No hamiltonian path. Hamiltonian Cycle

• We can check if a graph contains an Euler Cycle in linear time.

• Surprisingly, checking if a graph contains a Hamiltonian Path/Cycle is much harder!

• No polynomial time solution (i.e. O(Nk) ) is known.

51 No hamiltonian path. Contents

• Applications of DFS

• Euler Circuits

• Biconnectivity in Undirected Graphs.

• Finding Strongly Connected Components for Directed Graphs.

52 Connectivity

• An undirected graph is connected if there is a path from every vertex to every other vertex.

• Test for connectivity: See if DFS can reach all vertices.

unconnected53 graph Biconnectivity

• A graph is biconnected if there is no single vertex v, such that removing v will disconnect the remaining graph.

A B A

B D E C D F C

biconnected G E

54 not biconnected Biconnectivity

• A graph is biconnected if there is no single vertex v, such that removing v will disconnect the remaining graph.

A B A

B D E D F C

biconnected G E

55 not biconnected Biconnectivity

• A graph is biconnected if there is no single vertex v, such that removing v will disconnect the remaining graph.

A B A

B D E C D F C

biconnected G E

56 not biconnected Biconnectivity

• A graph is biconnected if there is no single vertex v, such that removing v will disconnect the remaining graph.

A B A

B D E C F C

biconnected G E

57 not biconnected Biconnectivity

• A graph is biconnected if there is no single vertex v, such that removing v will disconnect the remaining graph. C and D are articulation points. A B A

B D E

C D F C

biconnected G E

58 not biconnected Testing for Biconnectivity

• A graph G is biconnected if:

• G is connected.

• G does not contain any articulation points.

• Naive approach: • Remove each vertex. Test if the resulting graph is still connected. |V|·O(|V|+|E|) = O(|V|2 + |V|·|E|)

59 Depth First Spanning

• The steps taken by DFS can be illustrated as a (directed) . • Add a tree edge for every graph edge taken by DFS. • Add a back edge for every skipped edge.

A

B D E

C

60 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS.

A A

B D E

C

61 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS.

A A

B B D E

C

62 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS.

A A

B B D E

C C

63 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS.

A A

B B D E

C C D 64 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS. • Add a back edge for every skipped edge.

A A

B B D E

C C D 65 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS. • Add a back edge for every skipped edge.

A A

B B D E

C C D 66 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS. • Add a back edge for every skipped edge.

A A

B B D E

C C D E 67 Depth First Spanning Tree

• The steps taken by DFS can be illustrated as a (directed) spanning tree. • Add a tree edge for every graph edge taken by DFS. • Add a back edge for every skipped edge.

A A

B B D E

C C D E 68 Identifying Articulation Points (1)

• If the root of the DFS spanning tree has two outgoing tree edges, the root is an articulation point. C

B A B G

A C D F D C is an G E articulation E point. 69F Identifying Articulation Points (1)

• If the root of the DFS spanning tree has two outgoing tree edges, the root is an articulation point. A • Depends on which vertex we start DFS from. B B A

C

C D G F D A is not an E G E articulation F point. 70 Identifying Articulation Points (2) • Any non-root vertex v is an articulation point iff • v has a child w such that there is no back-edge from the subtree below w A to any ancestor of v. B B A

C

C D G F D C is an articulation G E E point because F 71 of G. Identifying Articulation Points (2) • Any non-root vertex v is an articulation point iff • v has a child w such that there is no back-edge from the subtree below w A to any ancestor of v. B B A

C

C D G F D D is an articulation G E E point because F 72 of E. Preorder Numbers • Assign numbers to each vertex in the order in which they are visited by DFS. • A For every tree edge (u,v): Num(u) < Num(v) 1 • For every back edge (u,v): Num(u) > Num(v) B 2 v Num(v) A 1 C B 2 3 C 3 G D 7 D 4 4 E 5 F 6 E 5 G 7 F 73 6 Low numbers

• For each vertex, find the lowest numbered vertex that is reachable by following a path that contains A at most one back edge. 1

B 2 v Num(v) Low(v) A 1 1 C B 2 3 C 3 G D 7 D 4 4 E 5 E F 6 5 G 7 F 74 6 Low numbers

• For each vertex, find the lowest numbered vertex that is reachable by following a path that contains A at most one back edge. 1

B 2 v Num(v) Low(v) A 1 1 C B 2 1 3 C 3 1 G D 7 D 4 1 4 E 5 E F 6 5 G 7 F 75 6 Low numbers

• For each vertex, find the lowest numbered vertex that is reachable by following a path that contains A at most one back edge. 1

B 2 v Num(v) Low(v) A 1 1 C B 2 1 3 C 3 1 G D 7 D 4 1 4 E 5 4 4 E F 6 5 G 7 7 F 76 6 Identifying Articulation Points • Any non-root vertex v is an articulation point iff • v has a child w such that there is no A back-edge from the subtree below w 1 to any ancestor of v. B 2 v Num(v) Low(v) A 1 1 C B 2 1 3 C 3 1 G D 7 D 4 1 4 E 5 4 4 E F 6 5 G 7 7 F 77 6 Identifying Articulation Points • Any non-root vertex v is an articulation point iff • v has a child w such that Low(w) ≥ Num(v) A 1

B 2 v Num(v) Low(v) A 1 1 C B 2 1 3 C 3 1 G D 7 D 4 1 4 E 5 4 4 E F 6 5 G 7 7 F 78 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 Low(v) = Num(u); } C 3 for all tree edges (v,u) { G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 Low(v) = Low(u); E } 5 } F 79 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 Low(v) = Num(u); } C 3 for all tree edges (v,u) { G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 Low(v) = Low(u); E } 5 } F 80 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); } C 3 for all tree edges (v,u) { G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 Low(v) = Low(u); E } 5 } F 81 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 3 3 for all tree edges (v,u) { G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 Low(v) = Low(u); E } 5 } F 82 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 3 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E } 5 } F 83 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 3 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 5 } 5 } F 84 6 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 3 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 5 } 5 } F 85 6 4 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 3 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 4 } 5 } F 86 6 4 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 3 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 4 } 5 } F 87 6 4 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 2 Low(v) = Num(u); C } 1 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 4 } 5 } F 88 6 4 Computing Low Numbers Recursively compute_low(v) { A Low(v) = Num(v) 1 1 for all back edges (v,u) { B if ( Num(u) < Low(v) ) 2 1 Low(v) = Num(u); C } 1 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 4 } 5 } F 89 6 4 Computing Low Numbers compute_low(v)Time to compute { preorder numbers: O(|V| +|E|) A Low(v)Time = Num(v) to compute low numbers: O(|V|+|E|) 1 1 for all back edges (v,u) { Time to check for articulation points: O(|V|+|E|) B if ( Num(u) < Low(v) ) 2 1 Low(v) = Num(u);Total: O(|V|+|E| ) C } 1 3 for all tree edges (v,u) { 7 G compute_low(u); D 7 if ( Low(u) < Low(v) ) 4 1 Low(v) = Low(u); E 4 } 5 } F 90 6 4 Contents

• Applications of DFS

• Euler Circuits

• Biconnectivity in Undirected Graphs.

• Finding Strongly Connected Components for Directed Graphs.

91 Connectivity in Directed Graphs • A is weakly connected if there is an undirected path from every vertex to every other vertex.

weakly connected92 graph Strongly Connected Graphs • A directed graph is strongly connected if there is a path from every vertex to every other vertex.

v Weakly connected, but not strongly connected (no other vertex can be reached from v).

93 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

94 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

95 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

96 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

97 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

98 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

99 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

100 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

101 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

102 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

103 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

104 Testing if a Graph is Strongly Connected • Run DFS to see if all vertices are reachable from some start node s.

s

• Reverse direction of edges and run DFS again.

105 Strongly Connected Components • Goal: Partition the graph into subgraphs such that each partition is strongly connected.

106 Strongly Connected Components • Goal: Partition the graph into subgraphs such that each partition is strongly connected.

A B G

D C F H

E J I

107 Strongly Connected Components • Goal: Partition the graph into subgraphs such that each partition is strongly connected.

A B G

D C F H

E J I

108 Strongly Connected Components • Goal: Partition the graph into subgraphs such that each partition is strongly connected.

A B G

D C F H

E J I

109 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G

D C F H

E J I

110 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G

D C F H

E J I E

111 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G

D C F H

D E J I E

112 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G

D C F H A D E J I E

113 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G

D C F H C A D E J I E

114 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G F B D C F H C A D E J I E

115 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node.

A B G F B D C F H C A D E J I E

116 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node. I J A B G F B D C F H C A

E J I D E

117 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node. H A B G I J F D C F H B C E J I A D E

118 Finding Strongly Connected Components • Run DFS and push all fully expanded nodes on a stack. If we get stuck, restart search at an arbitrary unvisited node. G H A B G I J F D C F H B C E J I A D E

119 Finding Strongly Connected Components

• Reverse the edge directions. G H A B G I J F D C F H B C E J I A D E

120 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong . Remove this component from the graph and stack. G • Continue until stack is empty. H A B G I J F D C F H B C E J I A D E

121 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. H A B G I J F D C F H B C E J I A D E

122 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. H A B G I J F D C F H B C E J I A D E

123 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. A B G I J F D C F H B C E J I A D E

124 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. A B G

F D C F H B C E J I A D E

125 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. A B G

D C F H B C E J I A D E

126 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. A B G

D C F H

E J I D E

127 Finding Strongly Connected Components • Pop the top vertex off the stack and run DFS. The set of visited nodes are a strong component. Remove this component from the graph and stack.

• Continue until stack is empty. A B G

D C F H

E J I

E

128