地址:http://poj.org/problem?id=1611
题意:n,m。n个人,编号0-n-1,m个组合:第一个数表示本集合个数,后面是成员。一个成员可以在多个集合里。0号是病人,跟她一个组合的全是病人,问一共有多少人患病。
解析:直接并查集基本模板,加入一个vis[]数组来记录与本节点相连的树的元素个数。最后输出vis[0]即可。vis[i]=1的一个初始化记得加。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<map> using namespace std; typedef long long ll; const int maxn=3e4+10; int pr[maxn]; int vis[maxn]; int sum=0; int n,m; int find(int x){ while(x!=pr[x]) { // pr[x]=pr[pr[x]]; x=pr[x]; } return x; } void join(int x1,int x2) { int f1=find(x1),f2=find(x2); if(f1!=f2) { pr[f1]=f2; vis[f2]+=vis[f1]; } return ; } void first() { for(int i=0;i<=n;i++) { pr[i]=i; vis[i]=1; } } int main() { while(scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; first(); int mid; while(m--) { int nn,x; scanf("%d",&nn); scanf("%d",&mid); for(int i=2;i<=nn;i++) { scanf("%d",&x); join(x,mid); } } cout<<vis[find(0)]<<endl; } }