嘿 , 狗日的没想到一次就过了 , 看来数据挺水![](https://images2015.cnblogs.com/blog/829161/201605/829161-20160526181018116-125476050.png)
![](https://images2015.cnblogs.com/blog/829161/201605/829161-20160526181023663-1124954583.png)
并查集的简单应用 . 直接 上 代码了.
1 #include<stdio.h>
2 #include<string.h>
3 #include<math.h>
4 #include<iostream>
5 #include<algorithm>
6 #include<queue>
7 #include<vector>
8 #include<set>
9 #include<stack>
10 #include<string>
11 #include<sstream>
12 #include<map>
13 #include<cctype>
14 #include<limits.h>
15 using namespace std;
16 #define len 1005
17 int father[len],sum;
18 int Find(int x) // 做了时间上的优化 ,但是 在空间复杂度上比较高
19 {
20 if(x!=father[x])
21 father[x]=Find(father[x]);
22 sum++;
23 return father[x];
24 }
25 bool Merge(int x,int y) // 做了时间复杂度上的优化 让并查集的 深度尽量 浅
26 {
27 int sum1,sum2;
28 sum=0;
29 x=Find(x);
30 sum1=sum; // x 的深度
31 sum=0;
32 y=Find(y);
33 sum2=sum; // y 的深度
34 if(x!=y)
35 {
36 if(sum1>sum2)
37 father[y]=x;
38 else
39 father[x]=y;
40 return true;
41 }
42 else
43 return false;
44 }
45 struct road
46 {
47 int x,y;
48 }a[len];
49 int main()
50 {
51 int n,m;
52 while(scanf("%d%d",&n,&m))
53 {
54 if(n==0)
55 break;
56 for(int i=0;i<=n;i++)
57 father[i]=i;
58 for(int i=0;i<m;i++)
59 {
60 int q,w;
61 scanf("%d%d",&q,&w);
62 Merge(q,w);
63 }
64 int mark=0;
65 for(int i=1;i<=n;i++)
66 {
67 father[i]=Find(i);
68 }
69 for(int i=1;i<=n;i++)
70 {
71 if(father[i]==i)
72 mark++;
73 }
74 printf("%d
",mark-1);
75 }
76 }