hdu1232 并查集

题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1213/

题目给定n个点和一些边,只要两点能通过某些边相连就相通。我们只要把所有的点连成一棵树就可以,一棵树有n-1条边,每次合并两棵树的时候边都会增加一条,我们只要知道合并的次数就可以知道已经有了多少条边,并查集的合并次数是n-1,因为最多n-1条边就使得每两个结点联通。

代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef unsigned int ui;
 4 typedef long long ll;
 5 typedef unsigned long long ull;
 6 #define pf printf
 7 #define mem(a,b) memset(a,b,sizeof(a))
 8 #define prime1 1e9+7
 9 #define prime2 1e9+9
10 #define pi 3.14159265
11 #define lson l,mid,rt<<1
12 #define rson mid+1,r,rt<<1|1
13 #define scand(x) scanf("%llf",&x) 
14 #define f(i,a,b) for(int i=a;i<=b;i++)
15 #define scan(a) scanf("%d",&a)
16 #define mp(a,b) make_pair((a),(b))
17 #define P pair<int,int>
18 #define dbg(args) cout<<#args<<":"<<args<<endl;
19 #define inf 0x3f3f3f3f
20 const int maxn=1e6+10;
21 int n,m,t;
22 inline int read(){
23     int ans=0,w=1;
24     char ch=getchar();
25     while(!isdigit(ch)){if(ch=='-')w=-1;ch=getchar();}
26     while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
27     return ans*w;
28 }
29 int f[maxn],cnt;
30 void init()
31 {
32     f(i,1,n)f[i]=i;
33     cnt=0;
34 }
35 int find(int x)
36 {
37     if(x==f[x])return x;
38     return f[x]=find(f[x]);
39 }
40 void Union(int x,int y)
41 {
42     int fx=find(x);
43     int fy=find(y);
44     if(fx==fy)return ;
45     else {
46         f[fx]=fy;
47         cnt++;    
48     }
49 }
50 int main()
51 {
52     //freopen("input.txt","r",stdin);
53     //freopen("output.txt","w",stdout);
54     std::ios::sync_with_stdio(false);
55     int a,b;
56     while(n=read())
57     {
58         init();
59         m=read();
60         f(i,1,m)a=read(),b=read(),Union(a,b);
61         pf("%d\n",n-1-cnt);
62         
63     }
64  } 

 

posted @ 2020-03-24 17:10  WA自动机~  阅读(87)  评论(0编辑  收藏  举报