zoukankan      html  css  js  c++  java
  • 畅通工程 ---并查集

     1 #include <cstdio>
     2 #include <cstring>
     3 using namespace std;
     4 int f[1010];//记录当前i的前驱(画完图是树形结构)
     5 
     6 int find(int x) //查找根节点
     7 { 
     8     int r=x;
     9     while(f[r]!=r)
    10         r=f[r];
    11     int i=x,j;
    12     while(i!=r)
    13     {
    14         j=f[i];
    15         f[i]=r;
    16         i=j;
    17     }
    18     return r;
    19 }
    20 
    21 int main()
    22 {
    23     int n,m,a,b;
    24     while(scanf("%d%d",&n,&m),n)
    25     {
    26         for(int i=0;i<=n;i++)
    27             f[i]=i;
    28         for(int i=0;i<m;i++)
    29         {
    30             scanf("%d%d",&a,&b);
    31             int x=find(a),y=find(b);//查找祖先,判断x,y是否为一个祖先
    32             if(x!=y) // 当ab的帮派不是一个的话,合并 在一起即一个大哥
    33                 f[x]=f[y];
    34         }
    35         int c=0;
    36         for(int i=1;i<=n;i++)
    37             if(f[i]==i)
    38             c++;
    39         printf("%d
    ",c-1);
    40     }
    41     return 0;
    42 }
    43         
    View Code

    我的理解:

    并查集 先是把各个顶点当成一个集合,构成n个集合后,用线段把集合连接起来,判断是否为连通图即判断f数组i位置元素是否等于i,如有一个则为连通图否则为非连通图

    find函数把线段的两个顶点x,y找到他所在集合的老大,判断线段的两个端点是否为一个老大,即用f【】数组找,f数组记录的前驱;

    找到两个老大之后,如不相等就把两个老大集合,合并起来。

  • 相关阅读:
    poj 3666 Making the Grade
    poj 3186 Treats for the Cows (区间dp)
    hdu 1074 Doing Homework(状压)
    CodeForces 489C Given Length and Sum of Digits...
    CodeForces 163A Substring and Subsequence
    CodeForces 366C Dima and Salad
    CodeForces 180C Letter
    CodeForces
    hdu 2859 Phalanx
    socket接收大数据流
  • 原文地址:https://www.cnblogs.com/WDKER/p/5467004.html
Copyright © 2011-2022 走看看