T-79.4202 Principles of Algorithmic Techniques Tutorial 4, October 15–16 Problems and Solutions
Autumn 2013
Advanced problems: 5. [Dasgupta [Dasgupta et al., al., Ex. 3.7] A bipartite graph is a graph G = (V , E ) whose vertices can be partitioned into two sets (V = = V 1 ∪ V 2 and V 1 ∩ V 2 = 0/ ) such that there are no edges between vertices in the same set (for instance, if u u , v ∈ V 1 , then there is no edge between u and v ). (a) Give a linear-time linear-time algorithm to determine whether an undirected graph is bipartite. Solution: Assume for a while that the graph G is connected. If G has a bipartition (V 1 , V 2 ), then on any path, every other vertex is in V 1 and every other in V 2 . Fix a vert vertex ex s ∈ V and let d (s, u) be the length of the shortest path from s to u ∈ V . We see that if the distance d (s, u) is even, u must be in the same partite set as s , and if d d (s, u) is odd, u must be in the other partite set. Consider an edge ( u, v) ∈ E . If the difference d (s, u) − d (s, v) is even, then in any bipartition, u and v would have to be in the same partite set, and the existence existence of the edge ( u, v) contradicts the bipartiteness. On the other hand, if d d (s, u) − d (s, v) is odd for all edges ( u, v), then we can define V 1 as the set of vertices u such that d (s, u) is odd, and V 2 as the set of the remaining vertices. Every Every edge has one endpoint endpoint in V 1 and the other in V 2 , so (V 1 , V 2 ) is a valid bipartition. Bipartiteness ss check using BFS Algorithm 1: 1: Bipartitene 1
function is-bipartite( function is-bipartite(G); Input: Input: Undirected graph G = (V , E ) Output: Output: “bipartite” or “not bipartite”
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
for all u ∈ V do dist do dist[u] ← ∞; for all s ∈ V do dist [s] = ∞ then if dist dist[s] ← 0; Q ← [s]; while Q is not empty do u ← EJECT(Q); for all edges ( u, v) ∈ E do do dist [v] = dist [u] then if dist return “not bipartite” end dist [v] = ∞ then if dist INJECT(Q, v); dist[v] ← dist[u] + 1; end end end end end return “bipartite”; 1
In fact, if ( u, v) ∈ E , the difference d (s, u) − d (s, v) can only be even if it is zero. We cannot have d (s, u) − d (s, v) > 1 because then we could take a shortest path from s to v and add the edge (v, u) to make a path from s to u with length d (s, v) + 1 < d (s, u), a contradiction. Similarly, the case d (s, u) − d (s, v) < −1 is impossible. To determine whether G is bipartite, we only need to pick some vertex s and check whether there is an edge (u, v) such that u and v are at an equal distance from s. Such an edge exists if and only if the graph is not bipartite. If G is not a connected graph, we repeat the process for every component. The algorithm is-bipartite above implements the idea in pseudocode. The algorithm is standard breadth-first search, except that on line 10 we check whether d (s, u) = d (s, v) and abort with a negative answer if equality holds. Also, we repeat the BFS for every component until all vertices have been visited. Like BFS, the algorithm has the linear run time of O (|V | + | E |). Instead of BFS, we could have used a depth-first search and checked that every back edge has one endpoint at an even depth and the other at an odd depth. (b) Prove the following formulation: an undirected graph is bipartite if and only if it contains no cycles of odd length. Solution: Assume that a graph G has a bipartition (V 1 , V 2 ). If the vertices u1 , . . . , uk form a cycle of G, then necessarily all odd-numbered vertices are in the same partite set as u 1 , and the even-numbered vertices are in the other partite set. There is an edge between u 1 and u k , so in particular, u k is even-numbered, and the length k of the cycle must be even. Thus, a bipartite graph has no cycles of odd length. For the other direction, we need to show that if G has no cycles of odd length, then it has a bipartition. Let us proceed by induction in the number of cycles in G. In the base case, G is acyclic, and its every component is a tree. From each component, pick an arbitrary vertex s , and designate every vertex at an odd distance from s in V 1 and every vertex at an even distance from s in V 2 . Because any edge connects a vertex at distance d to a vertex at distance d + 1, it has one endpoint in V 1 and the other in V 2 . Thus, (V 1 , V 2 ) is a bipartition of G . For the inductive case, assume that G has at least one cycle. Call its vertices u1 , . . . , uk . By assumption, k is even. Let G be the graph obtained by removing the edge (u1 , uk ) from G. Then G has (one or more) fewer cycles than G , and by the inductive hypothesis, G has a bipartition (V 1 , V 2 ). Let us show that (V 1 , V 2 ) is also a bipartition of G . As the vertices u1 , . . . , uk form a path in G and k is even, we know that one of u 1 , uk is in V 1 and the other is in V 2 . Therefore the edge ( u1 , uk ) has its endpoints in different partite sets. All other edges of G are also present in G , so they automatically fulfil the property. Therefore, G is bipartite. (c) At most how many colours are needed to colour an undirected graph with exactly one odd-length cycle? Solution: Let G be a simple undirected graph with exactly one odd-length cycle. Let u 1 , . . . , uk be the vertices on the cycle, where k ≥ 3 is odd. Two colours are not enough to colour the graph, because at least one pair of adjacent vertices on the odd cycle would get the same colour. However, if we remove the edge ( u1 , u2 ), then the remaining graph G has no odd cycles. The previous subproblem asserts that G has a bipartition (V 1 , V 2 ). We paint the 2
vertices in V 1 black and the vertices in V 2 white, which gives a valid colouring of G . In G, a third colour is needed because of the extra edge (u1 , u2 ), so we repaint the vertex u1 orange. Any edge incident to u1 then has endpoints of different colours because u1 is the only orange vertex. Any other edge has one black and one white endpoint. Thus, 3 colours are enough to colour the graph G. 6. [Dasgupta et al., Ex. 4.5] Often there are multiple shortest paths between two nodes of a graph. Give a linear-time algorithm for the following task. Input: Undirected graph G = (V , E ) with unit edge lengths; nodes u , v ∈ V . Output: The number of distinct shortest paths from u to v .
Solution: Breadth-first search gives one shortest path from u to v or to any other vertex reachable from u . To compute the number of shortest paths, we need to make an addition to the algorithm. Assume that the distance from u to some vertex x is 10. Then x has at least one neighbour y 1 whose distance from u is 9. Let us say that there are two more neighbours y 2 , y3 at distance 9 from u. Any shortest path from u to x can be constructed by choosing y ∈ { y1 , y2 , y3 } as the second last vertex, taking a shortest path from u to y, and adding the final edge ( y, x). Each choice y 1 , y 2 , or y3 gives a distinct set of paths. The total number of shortest paths from u to x is then the sum of the number of shortest paths from u to y 1 , y 2 , and y 3 . Generally, once we know the number of shortest paths from u to all vertices at distance d , we can compute the number of shortest paths to the vertices at distance d + 1 without actually enumerating the paths. We use BFS to go through the vertices in the order of increasing distance from the start vertex. The algorithm count-shortest-paths below performs a BFS starting from u. The number of shortest paths from u to any vertex x, denoted by paths[ x], is initialised to 0, except that there is 1 shortest path of length 0 from u to u . On line 14, we accumulate paths [ x] by summing paths[ y] for all neighbours y of x such that y is on a shortest path between u and x . In the end, paths [v] contains the number of shortest paths from u to v , or zero if v is unreachable from u . As a side effect, the algorithm finds the number of shortest paths from u to all vertices and not just to v , but this does not affect the worst-case run time. The run time of BFS is O (|V | + | E |), and count-shortest-paths stays in the same bound, assuming that integer addition is constanttime. Note that we might need to break this assumption in practice because the number of shortest paths can grow exponentially in the number of vertices.
3
Algorithm 2: Computing the number of shortest paths using BFS 1
function count-shortest-paths(G, u , v ); Input: Undirected graph G = (V , E ), vertices u and v Output: for all vertices x reachable from u , dist[ x] is set to the distance from u to x , and paths[ x] is set to the number of shortest paths from u to x . The return value is the number of shortest paths from u to v .
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
for all x ∈ V do dist[ x] ← ∞ ; paths[ x] ← 0 end ; dist[u] ← 0; paths[u] ← 1; Q ← [u]; while Q is not empty do x ← EJECT(Q); for all edges ( x, y) ∈ E do if dist [ y] = dist [ x] − 1 then paths[ x] ← paths[ x] + paths[ y]; end if dist [ y] = ∞ then INJECT (Q, y); dist[ y] ← dist[ x] + 1; end end end ; return paths[v]
4