zoukankan      html  css  js  c++  java
  • 判断图是否是无环图

    判断一个图是否为无环图:

    完整代码

    public class Cycle {
        private boolean[] marked;
        private int[] edgeTo;
        private Stack<Integer> cycle;
    
        /**
         * Determines whether the undirected graph {@code G} has a cycle and,
         * if so, finds such a cycle.
         *
         * @param G the undirected graph
         */
        public Cycle(Graph G) {
            if (hasSelfLoop(G)) return;
            if (hasParallelEdges(G)) return;
            marked = new boolean[G.V()];
            edgeTo = new int[G.V()];
            for (int v = 0; v < G.V(); v++)
                if (!marked[v])
                    dfs(G, -1, v);
        }
    
    
        // does this graph have a self loop?
        // side effect: initialize cycle to be self loop
        private boolean hasSelfLoop(Graph G) {
            for (int v = 0; v < G.V(); v++) {
                for (int w : G.adj(v)) {
                    if (v == w) {
                        cycle = new Stack<Integer>();
                        cycle.push(v);
                        cycle.push(v);
                        return true;
                    }
                }
            }
            return false;
        }
    
        // does this graph have two parallel edges?
        // side effect: initialize cycle to be two parallel edges
        private boolean hasParallelEdges(Graph G) {
            marked = new boolean[G.V()];
    
            for (int v = 0; v < G.V(); v++) {
    
                // check for parallel edges incident to v
                for (int w : G.adj(v)) {
                    if (marked[w]) {
                        cycle = new Stack<Integer>();
                        cycle.push(v);
                        cycle.push(w);
                        cycle.push(v);
                        return true;
                    }
                    marked[w] = true;
                }
    
                // reset so marked[v] = false for all v
                for (int w : G.adj(v)) {
                    marked[w] = false;
                }
            }
            return false;
        }
    
        /**
         * Returns true if the graph {@code G} has a cycle.
         *
         * @return {@code true} if the graph has a cycle; {@code false} otherwise
         */
        public boolean hasCycle() {
            return cycle != null;
        }
    
         /**
         * Returns a cycle in the graph {@code G}.
         * @return a cycle if the graph {@code G} has a cycle,
         *         and {@code null} otherwise
         */
        public Iterable<Integer> cycle() {
            return cycle;
        }
    
        private void dfs(Graph G, int u, int v) {
            marked[v] = true;
            for (int w : G.adj(v)) {
    
                // short circuit if cycle already found
                if (cycle != null) return;
    
                if (!marked[w]) {
                    edgeTo[w] = v;
                    dfs(G, v, w);
                }
    
                // check for cycle (but disregard reverse of edge leading to v)
                else if (w != u) {
                    cycle = new Stack<Integer>();
                    for (int x = v; x != w; x = edgeTo[x]) {
                        cycle.push(x);
                    }
                    cycle.push(w);
                    cycle.push(v);
                }
            }
        }
    
        /**
         * Unit tests the {@code Cycle} data type.
         *
         * @param args the command-line arguments
         */
        public static void main(String[] args) {
            In in = new In(args[0]);
            Graph G = new Graph(in);
            Cycle finder = new Cycle(G);
            if (finder.hasCycle()) {
                for (int v : finder.cycle()) {
                    StdOut.print(v + " ");
                }
                StdOut.println();
            }
            else {
                StdOut.println("Graph is acyclic");
            }
        }
    
    
    }
  • 相关阅读:
    HDU
    稀疏表(ST / Sparse Table)
    HDU
    HDU
    树状数组
    用 BitArray 来编写埃拉托斯特尼筛法
    BitArray 内置是逆序存储, 因此要自行实现正序输出
    位运算,位移,窗体
    按位运算,窗体程序,And,Or,Xor
    基数排序
  • 原文地址:https://www.cnblogs.com/hequnwang/p/14303468.html
Copyright © 2011-2022 走看看