use of chapter4.section1.OptimizedGraph in project algorithms-sedgewick-wayne by reneargento.
the class Exercise41_OddLengthDirectedCycle method hasOddLengthDirectedCycle.
// A digraph G has an odd-length directed cycle if and only if one (or more) of its strong components
// (when treated as an undirected graph) is nonbipartite
// Proof
// If the digraph G has an odd-length directed cycle, then this cycle will be entirely contained in one of the
// strong components. When the strong component is treated as an undirected graph, the odd-length directed cycle
// becomes an odd-length cycle.
// An undirected graph is bipartite if and only if it has no odd-length cycle.
// Suppose a strong component of G is nonbipartite (when treated as an undirected graph). This means that there is
// an odd-length cycle C in the strong component, ignoring direction.
// If C is a directed cycle, then we are done.
// Otherwise, if and edge v->w is pointing in the "wrong" direction, we can replace it with an odd-length path that
// is pointing in the opposite direction (which preserves the parity of the number of edges in the cycle).
// To see how, note that there exists a directed path P from w to v because v and w are in the same strong component.
// If P has odd length, then we replace edge v->w by P; if P has even length, then this path P combined with
// v->w is an odd-length cycle.
// O(V + E)
public boolean hasOddLengthDirectedCycle(Digraph digraph) {
KosarajuSharirSCC kosarajuSharirSCC = new KosarajuSharirSCC(digraph);
Set<Integer>[] strongComponents = (Set<Integer>[]) new HashSet[kosarajuSharirSCC.count()];
for (int scc = 0; scc < strongComponents.length; scc++) {
strongComponents[scc] = new HashSet<>();
}
for (int vertex = 0; vertex < digraph.vertices(); vertex++) {
int strongComponentId = kosarajuSharirSCC.id(vertex);
strongComponents[strongComponentId].add(vertex);
}
for (int scc = 0; scc < strongComponents.length; scc++) {
// Uses optimized graph to make the algorithm O(V + E) instead of O(V^2)
// (No need to initialize all adjacency lists for the subGraphs)
OptimizedGraph subGraph = new OptimizedGraph(digraph.vertices());
for (int vertex : strongComponents[scc]) {
for (int neighbor : digraph.adjacent(vertex)) {
if (strongComponents[scc].contains(neighbor)) {
subGraph.addEdge(vertex, neighbor);
}
}
}
TwoColor twoColor = new TwoColor(subGraph);
if (!twoColor.isBipartite()) {
return true;
}
}
return false;
}
Aggregations