zoukankan      html  css  js  c++  java
  • 深度优先搜索查找图中的所有连通分量

    使用深度优先搜索查找图中的连通分量:思想就是在深度优先搜索的基础上,在加上一个连通分量的数值标识( count),用于统计有几个连通分量。

    public class CC {
        private boolean[] marked;   // marked[v] = has vertex v been marked?
        private int[] id;           // id[v] = id of connected component containing v
        private int[] size;         // size[id] = number of vertices in given component
        private int count;          // number of connected components
    
        /**
         * Computes the connected components of the undirected graph {@code G}.
         *
         * @param G the undirected graph
         */
        public CC(Graph G) {
            marked = new boolean[G.V()];
            id = new int[G.V()];
            size = new int[G.V()];
            for (int v = 0; v < G.V(); v++) {
                if (!marked[v]) {
                    dfs(G, v);
                    count++;
                }
            }
        }
    
        /**
         * Computes the connected components of the edge-weighted graph {@code G}.
         *
         * @param G the edge-weighted graph
         */
        public CC(EdgeWeightedGraph G) {
            marked = new boolean[G.V()];
            id = new int[G.V()];
            size = new int[G.V()];
            for (int v = 0; v < G.V(); v++) {
                if (!marked[v]) {
                    dfs(G, v);
                    count++;
                }
            }
        }
    
        // depth-first search for a Graph
        private void dfs(Graph G, int v) {
            marked[v] = true;
            id[v] = count;
            size[count]++;
            for (int w : G.adj(v)) {
                if (!marked[w]) {
                    dfs(G, w);
                }
            }
        }
    
        // depth-first search for an EdgeWeightedGraph
        private void dfs(EdgeWeightedGraph G, int v) {
            marked[v] = true;
            id[v] = count;
            size[count]++;
            for (Edge e : G.adj(v)) {
                int w = e.other(v);
                if (!marked[w]) {
                    dfs(G, w);
                }
            }
        }
    
    
        /**
         * Returns the component id of the connected component containing vertex {@code v}.
         *
         * @param  v the vertex
         * @return the component id of the connected component containing vertex {@code v}
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         */
        public int id(int v) {
            validateVertex(v);
            return id[v];
        }
    
        /**
         * Returns the number of vertices in the connected component containing vertex {@code v}.
         *
         * @param  v the vertex
         * @return the number of vertices in the connected component containing vertex {@code v}
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         */
        public int size(int v) {
            validateVertex(v);
            return size[id[v]];
        }
    
        /**
         * Returns the number of connected components in the graph {@code G}.
         *
         * @return the number of connected components in the graph {@code G}
         */
        public int count() {
            return count;
        }
    
        /**
         * Returns true if vertices {@code v} and {@code w} are in the same
         * connected component.
         *
         * @param  v one vertex
         * @param  w the other vertex
         * @return {@code true} if vertices {@code v} and {@code w} are in the same
         *         connected component; {@code false} otherwise
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         * @throws IllegalArgumentException unless {@code 0 <= w < V}
         */
        public boolean connected(int v, int w) {
            validateVertex(v);
            validateVertex(w);
            return id(v) == id(w);
        }
    
        /**
         * Returns true if vertices {@code v} and {@code w} are in the same
         * connected component.
         *
         * @param  v one vertex
         * @param  w the other vertex
         * @return {@code true} if vertices {@code v} and {@code w} are in the same
         *         connected component; {@code false} otherwise
         * @throws IllegalArgumentException unless {@code 0 <= v < V}
         * @throws IllegalArgumentException unless {@code 0 <= w < V}
         * @deprecated Replaced by {@link #connected(int, int)}.
         */
        @Deprecated
        public boolean areConnected(int v, int w) {
            validateVertex(v);
            validateVertex(w);
            return id(v) == id(w);
        }
    
        // throw an IllegalArgumentException unless {@code 0 <= v < V}
        private void validateVertex(int v) {
            int V = marked.length;
            if (v < 0 || v >= V)
                throw new IllegalArgumentException("vertex " + v + " is not between 0 and " + (V-1));
        }
    
        /**
         * Unit tests the {@code CC} 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);
            CC cc = new CC(G);
    
            // number of connected components
            int m = cc.count();
            StdOut.println(m + " components");
    
            // compute list of vertices in each connected component
            Queue<Integer>[] components = (Queue<Integer>[]) new Queue[m];
            for (int i = 0; i < m; i++) {
                components[i] = new Queue<Integer>();
            }
            for (int v = 0; v < G.V(); v++) {
                components[cc.id(v)].enqueue(v);
            }
    
            // print results
            for (int i = 0; i < m; i++) {
                for (int v : components[i]) {
                    StdOut.print(v + " ");
                }
                StdOut.println();
            }
        }
    }
  • 相关阅读:
    详解Winform多线程编程基本原理
    asp.net 文件夹和文件的创建、删除
    sql server 查询表名,存储过程,列名等
    随机输出数组中的一个数
    C# 获取Access数据库中所有表名及其列名、列类型
    Oracle 数据库小记
    Oracle11g、PLSQL、Winfrom环境搭建
    SELECT INTO 和 INSERT INTO SELECT 两种表复制语句
    Android开发中用到的框架、库介绍
    Android数据存储
  • 原文地址:https://www.cnblogs.com/hequnwang/p/14303015.html
Copyright © 2011-2022 走看看