您的位置:首页 > 其它

POJ 1611(并查集+知识)

2016-01-24 10:36 218 查看
并查集主要是两个过程,一个是并,一个是查

原理是用一个数组p[i]保存每个i的根节点,如果根节点一样则在同一个集合里,所以只有根节点p[i]=i;

查:

int find(int x){return p[x]==x?x:p[x]=find(p[x]);}

并:

void Union(int x,int y)

{

  int xx = find(x);int yy=find(y);

  if(xx!=yy)//不在一个集合里

    p[xx]=yy;

}

#include <cstdio>
#include <iostream>
#include <queue>
using namespace std;

#define sf scanf
#define pf printf
#define debug printf("!\n")
#define blank printf("\n")
#define mem(a,b) memset(a,b,sizeof(a))

const int MaxN = 30010;
const int INF = 1<<27;

int p[MaxN],a[MaxN];

int m,n;

int find(int x){return p[x]==x?x:p[x]=find(p[x]);}

void Union(int x,int y)
{
int rx = find(x);
int ry = find(y);
p[rx] = ry;
}

int main()
{
int i,j,k;
while(~scanf("%d%d",&n,&m),n+m)
{
i = 0;
mem(p,0);
mem(a,0);
for(j=0;j<n;j++)
p[j] = j;
while(m--)
{
sf("%d",&k);
for(i=0;i<k;i++)
{
sf("%d",&a[i]);
}
for(i=1;i<k;i++)
{
Union(a[i-1],a[i]);
}
}
int cnt = 0;
for(i = 0;i<n;i++)
{
if(find(i)==find(0))
cnt++;
}
pf("%d\n",cnt);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: