太难的搞不过,只能来写简单的了
POJ2524
无所不在的宗教
世界上宗教何其多。假设你对自己学校的学生总共有多少种宗教信仰很感兴趣。学校有n个学生,但是你不能直接问学生的信仰,不然他会感到很不舒服的。有另外一个方法是问m对同学,是否信仰同一宗教。根据这些数据,相信聪明的你是能够计算学校最多有多少种宗教信仰的。
【输入格式】
可以输入多个测试用例(Case),每一个用例的第一行包含整数n和m,n表示学生编号(1-n),在接下来的m行中,每一行包含两个整数,对应信仰同一宗教的两名学生的编号,输入结束行为n = m=0。
【输出格式】
输出每一个测试用例中包含的学生信仰的最大宗教数量。
样例输入
10 9 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 1 10 10 4 2 3 4 5 4 8 5 8 0 0
样例输出
Case 1: 1 Case 2: 7
代码
1 #include <iostream> 2 using namespace std; 3 4 const int MAXN=50001; 5 int pa[MAXN]; 6 int rank[MAXN]; 7 8 void make_set(int x){ 9 pa[x] = x; 10 rank[x] = 0; 11 } 12 13 int find_set(int x){ 14 if(x != pa[x]){ 15 pa[x] = find_set(pa[x]); 16 } 17 return pa[x]; 18 } 19 20 void union_set(int x,int y){ 21 x = find_set(x); 22 y = find_set(y); 23 24 if(rank[x] > rank[y]){ 25 pa[y] = x; 26 } 27 else{ 28 pa[x] = y; 29 if(rank[x] == rank[y]){ 30 rank[y]++; 31 } 32 } 33 } 34 35 36 int main(void){ 37 int n,m,kase=0,count; 38 while(scanf("%d%d",&n,&m) == 2 && n!=0 && m!=0){ 39 int i; 40 for(i=1;i<=n;i++){ 41 make_set(i); 42 } 43 for(i=0;i<m;i++){ 44 int a,b; 45 scanf("%d%d",&a,&b); 46 union_set(a,b); 47 } 48 count = 0; 49 for(i=1;i<=n;i++){ 50 if(i == pa[i]){ 51 count++; 52 } 53 } 54 printf("Case %d: %d\n",++kase,count); 55 } 56 return 0; 57 }