0
点赞
收藏
分享

微信扫一扫

POJ--1611经典并查集

Ad大成 2022-09-26 阅读 125

地址:​​http://poj.org/problem?id=1611​​

POJ--1611经典并查集_#include

 


题意: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;
}
}

 



举报

相关推荐

0 条评论