题目大意:
一个学校有n个学生(0 < n ≤ 50,000),现给出m个条件(0 ≤ m ≤ n(n-1)/2),每个条件的形式为"x y",x、y为学生的编号(从1开始),表示x和y信仰同一种宗教,现要你统计可能的最大不同信仰总数,注意,没在条件中出现的所有学生当做各自具有不同的信仰。
现有多个测例,每个测例中给出n和m,程序以n、m = 0结束,以及m个条件,对于每个测例要求输出不同宗教的最大可能数量。
注释代码:
/*
* Problem ID : POJ 2524 Ubiquitous Religions
* Author : Lirx.t.Una
* Language : C
* Run Time : 313 ms
* Run Memory : 348 KB
*/
#include <stdio.h>
//学生的最大数量
#define MAXN 50000
int fath[MAXN + 1];//一定要用int,short就WA,可能跟编译器有关
int
find(int x) {
return x == fath[x] ? x : ( fath[x] = find( fath[x] ) );
}
int
main() {
int t;//测例数
int n, m;//学生数和条件数
int a, b;//临时接受学生的编号
int fa, fb;//a、b的根结点
int i;//计数变量
t = 0;
while ( scanf("%d%d", &n, &m), n ) {
for ( i = 1; i <= n; i++ ) fath[i] = i;//初始化
while ( m-- ) {
scanf("%d%d", &a, &b);
fa = find(a);
fb = find(b);
//一开始不同宗教数量就为n
//随着条件的增加n逐渐减少
if ( fa != fb ) {//如果两个不在一个集合,则合并
//同时就多了一种相同的宗教,同时也就意味着少了一种
//不同的宗教
fath[fb] = fa;
n--;
}
}
printf("Case %d: %d\n", ++t, n);
}
return 0;
}
无注释代码:
#include <stdio.h>
#define MAXN 50000
int fath[MAXN + 1];
int
find(int x) {
return x == fath[x] ? x : ( fath[x] = find( fath[x] ) );
}
int
main() {
int t;
int n, m;
int a, b;
int fa, fb;
int i;
t = 0;
while ( scanf("%d%d", &n, &m), n ) {
for ( i = 1; i <= n; i++ ) fath[i] = i;
while ( m-- ) {
scanf("%d%d", &a, &b);
fa = find(a);
fb = find(b);
if ( fa != fb ) {
fath[fb] = fa;
n--;
}
}
printf("Case %d: %d\n", ++t, n);
}
return 0;
}
单词解释:
ubiquitous:adj, 无所不在的
religion:n, 宗教,宗教信仰
infeasible:adj, 不可行的
belief:n, 信仰,教义
subscribe:vt, 签署,赞成,订阅
subscribe to:vt, 签署,赞成,订阅