POJ 2524 Ubiquitous Religions (并查集)
Description
当今世界有很多不同的宗教,很难通晓他们。你有兴趣找出在你的大学里有多少种不同的宗教信仰。你知道在你的大学里有n个学生(0 < n <= 50000).你无法询问每个学生的宗教信仰。此外,许多学生不想说出他们的信仰。避免这些问题的一个方法是问m(0 <= m <= n(n - 1)/ 2)对学生, 问他们是否信仰相同的宗教( 例如他们可能知道他们两个是否去了相同的教堂) 。在这个数据中,你可能不知道每个人信仰的宗教,但你可以知道校园里最多可能有多少个不同的宗教。假定每个学生最多信仰一个宗教。
Input
有多组数据。对于每组数据:第一行:两个整数n和m。以下m行:每行包含两个整数i和j,表示学生i和j信仰相同的宗教。学生编号从1到n。输入的最后一行中,n = m = 0。
Output
对于每组测试数据,输出一行,输出数据序号( 从1开始) 和大学里不同宗教的最大数量。(参见样例)
解题思路:
解题思路:
典型的并查集,利用并查集,最后统计下根节点的数量就OK了(pre[i] == i)。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <cctype> 7 #include <algorithm> 8 using namespace std; 9 const int MAXN = 1e5 + 3; 10 int pre[MAXN]; 11 int a[MAXN]={0}; 12 int Find(int x) 13 { 14 int r = x; 15 while(pre[r] != r) 16 { 17 r = pre[r]; 18 } 19 int i = x,j; 20 while(pre[i] != r) 21 { 22 j = i; 23 i = pre[i]; 24 pre[j] = r; 25 } 26 return r; 27 } 28 29 void Mix(int a,int b) 30 { 31 int x = Find(a); 32 int y = Find(b); 33 if(x > y) 34 { 35 pre[x] = y; 36 } 37 if(x < y) 38 { 39 pre[y] = x; 40 } 41 } 42 43 44 void Mst(int n) 45 { 46 for(int i = 1; i <= n; i++) 47 { 48 pre[i] = i; 49 } 50 } 51 52 int main() 53 { 54 //freopen("in.txt","r",stdin); 55 // freopen("out.txt","w",stdout); 56 int m,n; 57 int kas = 0; 58 while(~scanf("%d%d",&n,&m)&&(n||m)) 59 { 60 Mst(n); 61 while(m--) 62 { 63 int a,b; 64 scanf("%d%d",&a,&b); 65 Mix(a,b); 66 } 67 int ans = 0; 68 for(int i = 1; i <= n; i++) 69 if(pre[i] == i) 70 ans++; 71 printf("Case %d: ",++kas); 72 cout << ans <<endl; 73 } 74 return 0; 75 }
It's not numeral,character and punctuation .It's my life.