// 600K 282MS G++
#include <cstdio>
#include <cstring>
using namespace std;
const int MAX = 50010;
int UF_set[MAX];
char typeArray[MAX];
int caseNum = 1;
int studentNum;
int pairNum;
void UF_getSetId(int studentId) {
if (UF_set[studentId] == 0) {
return;
}
int parentId = UF_set[studentId];
while(UF_set[parentId] != parentId) {
parentId = UF_set[parentId];
}
UF_set[studentId] = parentId;
}
void UF_fill(int studentA, int studentB) {
UF_getSetId(studentA);
UF_getSetId(studentB);
int ASetId = UF_set[studentA];
int BSetId = UF_set[studentB];
if (!ASetId && !BSetId) {
UF_set[studentA] = studentA;
UF_set[studentB] = studentA;
} else if (ASetId && !BSetId) {
UF_set[studentB] = ASetId;
} else if (!ASetId && BSetId) {
UF_set[studentA] = BSetId;
} else if (ASetId && BSetId) {
if (ASetId != BSetId) {
UF_set[studentB] = ASetId;
UF_set[BSetId] = ASetId;
}
}
}
int getTotalNum() {
int reglionNum = 0;
for (int i = 1; i <= studentNum; i++) {
UF_getSetId(i);
if (UF_set[i] == 0) {
reglionNum++;
} else {
if (!typeArray[UF_set[i]]) {
typeArray[UF_set[i]] = 1;
reglionNum++;
}
}
}
return reglionNum;
}
int main() {
while(scanf("%d %d", &studentNum, &pairNum) != EOF) {
if (!studentNum && !pairNum) {
return 0;
}
memset(UF_set, 0, sizeof(UF_set));
memset(typeArray, 0, sizeof(typeArray));
int studentA, studentB;
for (int i = 1; i <= pairNum; i++) {
scanf("%d %d", &studentA, &studentB);
UF_fill(studentA, studentB);
}
int reglionNum = getTotalNum();
printf("Case %d: %d\n", caseNum, reglionNum);
caseNum++;
}
}
并查集基础题,没啥说的,注意最后求reglion的个数时,除了已经进入并查集的那些学生外(这部分学生的reglion个数就是并查集中集合的个数),其他的没有被问到(进入并查集)的学生,每个人算一种reglion.