POJ_1611_The Suspects(并查集)
2014-03-13 20:44
405 查看
题型:并查集
题意:
有编号为0~n-1的n个人,其中若干人组过m个组活动过,每个组有k个人,如果组内有一个人是非典疑似者,则整个组的人都认为是非典疑似者,起始0号为非典疑似者,问最终多少人被定为非典疑似者。
分析:
利用并查集,将每一个组里的人合并为一个集合,最后看有多少个人和0号是一个集合。
代码:
题意:
有编号为0~n-1的n个人,其中若干人组过m个组活动过,每个组有k个人,如果组内有一个人是非典疑似者,则整个组的人都认为是非典疑似者,起始0号为非典疑似者,问最终多少人被定为非典疑似者。
分析:
利用并查集,将每一个组里的人合并为一个集合,最后看有多少个人和0号是一个集合。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #define MAXN 34567 using namespace std; int n,m,k; int father[MAXN];//father[x]表示x的父节点 int rank[MAXN];//rank[x]表示x的秩 void Make_Set(int x){//初始化 father[x] = x; rank[x] = 0; } /*查找x元素的集合所在的集合,回溯时压缩路径*/ int Find_Set(int x){ if(x != father[x]){ father[x] = Find_Set(father[x]);//精华 } return father[x]; } /* 按秩合并x,y所在的集合 if else结构不是绝对的,具体根据情况变化 但是,宗旨是不变的,按秩合并,实时更新秩 */ void Union(int x,int y){ x = Find_Set(x); y = Find_Set(y); if(x == y) return; if(rank[x]>rank[y]){ father[y] = x; } else{ if(rank[x] == rank[y]){ rank[y]++; } father[x] = y; } } int main(){ while(1){ int tmp,x; scanf("%d%d",&n,&m); if(n==0 && m==0) break; for(int i=0;i<n;i++){ Make_Set(i); } for(int i = 0;i < m;i++){ scanf("%d",&k); scanf("%d",&x); k--; while(k--){ scanf("%d",&tmp); Union(x,tmp); } } int ans = 1; for(int i=1;i<n;i++){ if(Find_Set(0) == Find_Set(i)) ans++; } printf("%d\n",ans); } return 0; }
相关文章推荐
- poj 1611-The Suspects:并查集
- [ACM] POJ 1611 The Suspects (并查集,输出第i个人所在集合的总人数)
- poj 1611 The Suspects(简单并查集)
- POJ-1611 The Suspects( 并查集 )
- POJ-1611 The Suspects (并查集模板题)
- POJ 1611 The Suspects(简单并查集)
- poj1611——The Suspects(并查集)
- The Suspects(POJ 1611 并查集)
- POJ 1611 The Suspects (并查集)
- poj 1611-The Suspects:并查集
- POJ 1611 The Suspects (并查集)
- POJ 1611 The Suspects(并查集)
- POJ 1611 The Suspects (并查集)
- POJ 1611 The Suspects(带权并查集)
- 【POJ 1611】 The Suspects(并查集练习)
- poj 1611 The Suspects (并查集)
- POJ 1611 The Suspects (并查集)
- POJ - 1611 - The Suspects(并查集)
- POJ 1611 The Suspects(并查集)
- POJ 1611 The Suspects(并查集)