使用并查集判断图中是否含有环

使用并查集判断图中是否含有环

 1 // function:
 2 // 使用并查集判断图中是否含有环
 3 // 须知:parent[x1] = x2 表示顶点x1的父节点是x2
 4 #include<iostream>
 5 using namespace std;
 6 
 7 #define VERTICES 6
 8 
 9 // 初始化
10 void initialize(int parent[], int rank[]){
11     for(int i=0; i < VERTICES; i++){
12         parent[i] = -1;// 初始化每个顶点的父节点是-1
13         rank[i] = 0;// 用来路径压缩
14     }
15 }
16 
17 // 查找节点的根
18 int find_root(int x, int parent[]){
19     int x_root = x;
20     while(parent[x_root] != -1){
21         x_root = parent[x_root];
22     }
23     return x_root;
24 }
25 
26 // 集合合并
27 int union_vertices(int x, int y, int parent[], int rank[]){
28     // 1 -- 合并成功
29     // 0 -- 合并失败,即x,y已经在同一个集合内
30     int x_root = find_root(x, parent);
31     int y_root = find_root(y, parent);
32     if(x_root == y_root)
33         return 0;
34     else{ // 路径压缩
35         if(rank[x_root] > rank[y_root])
36             parent[y_root] = x_root;
37         else if(rank[x_root] < rank[y_root])
38             parent[x_root] = y_root;
39         else{
40             parent[x_root] = y_root;
41             rank[y_root]++;
42         }
43         return 1;
44     }
45 }
46 
47 int main(int argc, char const *argv[]) {
48     int parent[VERTICES];
49     int rank[VERTICES];
50     /* 代码中的图如下所示,1, 3, 4, 2组成一个环
51      *        0
52      *          \
53      *            1
54      *          /   \
55      *        2         3
56      *        |   \   |
57      *        5         4
58     */
59     int edges[6][2] = { {0, 1}, {1, 2}, {1, 3},
60                         {2, 5}, {3, 4}, {2, 4} };// 图中所有的边集合
61     initialize(parent, rank);
62     for(int i=0; i < 6; ++i){
63         int x = edges[i][0];
64         int y = edges[i][1];
65         if(union_vertices(x, y, parent, rank) == 0){
66             cout<<"Cycle detected."<<endl;
67             return 0;
68         }
69     }
70     cout<<"No cycle."<<endl;
71     return 0;
72 }

运行结果:

Cycle detected.
[Finished in 1.1s]

参考资料:

黄浩杰,并查集(Disjoint-set union),youtube

posted on 2019-01-15 17:34  wangzhch  阅读(1864)  评论(0编辑  收藏  举报

导航