HDU-1213-How Many Tables
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1213
/*
程序分析:
题意背景:生日聚会,邀请朋友来做客,不是所有的朋友都互相认识,所以人都不愿跟陌生人一起坐,现在主人要统计聚会需要多少张桌子,
认识的都坐在一张桌子上,不认识的就另起炉灶,现在输入朋友个数还有朋友之间认识的组合,让你统计需要几张桌子。用计算机思想想的话其实
就是让你统计有棵树,一棵树代表一张桌子。
解决方法:
用并查集就可以,把认识的都合并在一棵树上,最后统计有几颗树就可以。结果集是树的数量。
*/
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 4 const int Max = 1000+10; 5 int Far[Max]; 6 int Rank[Max]; 7 int Sign[Max]; 8 9 void Make_set(int n) 10 { 11 int i; 12 for(i=0; i<=n; i++) 13 { 14 Far[i] = i; 15 } 16 memset(Rank, 0, sizeof(Rank)); 17 memset(Sign, 0, sizeof(Sign)); 18 } 19 20 int Find_set(int x) 21 { 22 if(Far[x] != x) 23 return Far[x] = Find_set(Far[x]); 24 return Far[x]; 25 } 26 27 void Unio(int a, int b) 28 { 29 a = Find_set(a); 30 b = Find_set(b); 31 if(a == b) 32 return; 33 if(Rank[a] < Rank[b]) 34 Far[a] = b; 35 else if(Rank[a] > Rank[b]) 36 Far[b] = a; 37 else 38 { 39 Far[a] = b; 40 Rank[b]++; 41 } 42 } 43 44 int main() 45 { 46 int t; 47 int n, m; 48 int a, b; 49 cin>>t; 50 while(t--) 51 { 52 cin>>n>>m; 53 Make_set(n); 54 for(int i=1; i<=m; i++) 55 { //合并 56 scanf("%d%d", &a, &b); 57 Unio(a, b); 58 } 59 int ans=0; 60 //while(n--) //不能用while, 用了就WA,因为进入循环后n的值就减一了 61 for(int j=1; j<=n; j++) 62 { //统计有几棵树 63 //if(Find_set(n) == n) //不能这样用 64 if(Find_set(j) == j) 65 ans ++; 66 } 67 cout<<ans<<endl; 68 } 69 return 0; 70 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 using namespace std; 3 #define max 1010 4 5 int p[max]; 6 bool k[max]; 7 8 int find(int pos) 9 { 10 if(p[pos]==-1)return pos; 11 return p[pos]=find(p[pos]); 12 } 13 int uni(int x,int y) 14 { 15 int a=find(x); 16 int b=find(y); 17 if(a==b)return 0; 18 p[a]=b; 19 return 1; 20 } 21 22 int main() 23 { 24 int temp; 25 int a,b; 26 int n,m; 27 int T; 28 cin>>T; 29 while(T--) 30 { 31 cin>>n>>m; 32 //初始化 33 for(int i=1;i<=n;i++) 34 { 35 p[i]=-1; 36 k[i]=0; 37 } 38 //输入 合并 39 for(int i=1;i<=m;i++) 40 { 41 cin>>a>>b; 42 uni(a,b); 43 } 44 //标记 45 for(int i=1;i<=n;i++) 46 { 47 temp=find(i); 48 k[temp]=1; 49 } 50 //统计 51 int add=0; 52 for(int i=1;i<=n;i++) 53 { 54 if(k[i]==1) 55 add++; 56 } 57 printf("%d\n",add); 58 /*char c[10]; 59 if(T) 60 gets(c);*/ 61 } 62 return 0; 63 }