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


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

     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

  • 相关阅读:
    译:编程面试的10大算法概念汇总
    Android内存优化之封装九宫格
    Android Java 程序员必备开发工具
    译:如何成为一个通晓多种编程语言的程序员
    8大排序算法图文讲解
    Android酷炫实用的开源框架(UI框架)
    Android动态加载字节码
    利用无效字节码指令引发逆向工具崩溃(二)
    oracle 12c linux服务器启动监听
    oracle无主键去重方法
  • 原文地址:https://www.cnblogs.com/iwangzhengchao/p/10273203.html
Copyright © 2020-2023  润新知