并查集 POJ2524

mac2022-06-30  27

/* 如果两个学生的信仰一样 则总的宗教个数减一 */ #include < iostream > #include < stdio.h > using namespace std; int sum,n,m; int father[ 50001 ]; void makeset( int x){ for ( int i = 1 ;i <= x;i ++ ) { father[i] = i; }} int findset( int x) // { if (x != father[x]) { father[x] = findset(father[x]); } // 回溯 return father[x];} void Union( int a, int b){ int x = findset(a); int y = findset(b); if (x == y) return ; sum = sum - 1 ; father[y] = x;} int main(){ int l = 1 ; while (scanf( " %d%d " , & n, & m) != EOF) { if (n == 0 && m == 0 ) break ; sum = n; makeset(n); int first,second; for ( int i = 1 ;i <= m;i ++ ) { scanf( " %d%d " , & first, & second); Union(first,second); } printf( " Case %d: %d\n " ,l,sum); l ++ ; } return 0 ;} 已知有n个大学生,其中有m对宗教信仰相同的学生,请你估算这n个学生中最多有多少种宗教信仰。 依旧是简单的并查集应用。宗教信仰的最大值为学生数n,因此一开始把n个学生作为n个集合,对给出的每对大学生 a 和 b ,如果他们在不同的集合,就合并他们,然后宗教数减一。 这次依旧用到了路径压缩,只不过上一次写的是非递归,这次写了一个递归版本。也就是搜索完成回溯的时候"顺便"将当前节点的父节点直接指向祖先节点。题目大意解释来自Slyar Home (www.slyar.com) 转载请注明,谢谢合作。

转载于:https://www.cnblogs.com/cyiner/archive/2011/05/16/2048229.html

最新回复(0)