Problem Address:http://poj.org/problem?id=1611
【前言】
记得很久以前就接触了并查集。
但是那个时候的实现现在感觉起来很粗糙。
虽然很多时候拿那个模板一贴答案就出来了。
但是现在看来效率似乎不咋地。
前不久也做了一道并查集。
今天又弄了道并查集。
于是直接把代码放这儿。
就当是模板吧。
实现起来还是挺好的。
【思路】
并查集。
【代码】
#include <iostream>
using namespace std;
const int maxn = 30000;
int father[maxn+5];//记录父节点
int len[maxn+5];//记录以该点为根的集合元素的个数
void init(int n)//并查集的初始化
{
int i;
for (i=0; i<n; i++)
{
father[i] = i;
len[i] = 1;
}
}
inline int getroot(int x)//获得某节点的根节点(不同于父节点),并压缩路径
{
int r = x;
while(father[r]!=r)
{
r = father[r];
}
while(father[x]!=r)
{
father[x] = r;
x = father[x];
}
return r;
}
inline void join(int s, int x)//把s和x合并起来
{
int a = getroot(s);
int b = getroot(x);
if (a!=b)
{
father[a] = b;
len[b] += len[a];
}
}
int main()
{
int n, m, k;
int i, j, x, s;
while(scanf("%d %d", &n, &m)!=EOF)
{
if (n==0 && m==0) break;
init(n);
for (i=0; i<m; i++)
{
scanf("%d", &k);
if (k==0) continue;
scanf("%d", &s);
for (j=1; j<k; j++)
{
scanf("%d", &x);
join(s, x);
}
}
printf("%d\n", len[getroot(0)]);
}
return 0;
}