Search in sources :

Example 1 with OptimizedGraph

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;
}
Also used : TwoColor(chapter4.section1.TwoColor) HashSet(java.util.HashSet) Set(java.util.Set) OptimizedGraph(chapter4.section1.OptimizedGraph)

Aggregations

OptimizedGraph (chapter4.section1.OptimizedGraph)1 TwoColor (chapter4.section1.TwoColor)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1