题意:中文题目
思路:按照HDU1213来做。http://www.cnblogs.com/xcw0754/p/4607813.html
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 const int N=1005; 5 int pre[N]; //结点i的上级 6 inline void init(int n){for(int i=1; i<=n; i++) pre[i]=i;} //将上级初始化为自己 7 8 int find(int x) //找x的上级 9 { 10 int k=x; 11 while(pre[x]!=x) x=pre[x]; //找上级 12 13 //优化:路径压缩 14 int tmp; 15 while(pre[k]!=x) 16 { 17 tmp=pre[k]; 18 pre[k]=x; 19 k=tmp; 20 } 21 return x; 22 } 23 24 void joint(int a,int b) //将a和b合并为一个集合 25 { 26 a=find(a); 27 b=find(b); 28 if(a!=b) pre[a]=b; 29 } 30 31 int check(int n) //查查到底需要几张桌子 32 { 33 set<int> sett; 34 for(int i=1; i<=n; i++) find(i); //防漏网之鱼,将所有人的老大推到最顶。 35 for(int i=1; i<=n; i++) sett.insert(pre[i]); 36 return sett.size(); 37 } 38 int main() 39 { 40 //freopen("e://input.txt", "r", stdin); 41 int n, m, a, b; 42 while(scanf("%d",&n),n>0) 43 { 44 scanf("%d",&m); 45 init(n); 46 for(int i=0; i<m; i++) 47 { 48 scanf("%d%d",&a,&b); 49 joint(a,b); 50 } 51 printf("%d ",check(n)-1); 52 } 53 54 55 return 0; 56 }