poj1611并查集求元素所在集合的元素总数

并查集应用:求某元素所在集合的元素个数
题目:已知有n个人,m个团队,已知0号选手有病毒,病毒会传染给他所在任一小组中的人。
求最后有病毒的人的个数。
思路1:对相同团队的人进行合并,最后输出与0在同一集合的元素个数。
即是否满足find(0)==find(i)。

思路2:对相同团队的人进行合并,合并过程中对集合元素个数num也和并,最后找到0的祖先的num即可

思路1:

#include 
#include 
#define N 30005

int f[N];
int n, m;

void init()
{
	for (int i = 0; i < n; i++)
		f[i] = i;
}

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

void merge(int x, int y)
{
	int t1 = find(x), t2 = find(y);
	if (t1 != t2)
		f[t2] = t1;
}

int main()
{
	while (~scanf("%d%d", &n, &m) && (n || m))
	{
		int t, u, v;
		init();
		for (int i = 0; i < m; i++)
		{
			scanf("%d", &t);
			if (t > 0)
			{
				scanf("%d", &u);
				for (int i = 0; i < t - 1; i++)
				{
					scanf("%d", &v);
					merge(u, v);
				}
			}
		}
		int ans = 0;
		for (int i = 0; i < n; i++)
			if (find(i) == find(0))	ans++;
		printf("%d\n", ans);
	}
	return 0;
}
思路2:
#include 
#include 
#define N 30005

int f[N];
int num[N];//记录当前元素所在集合的元素个数
int n, m;

void init()
{
	for (int i = 0; i < n; i++)
	{
		f[i] = i;
		num[i] = 1;//初始化每个元素所在集合中总元素的个数
	}
}

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

void merge(int x, int y)
{
	int t1 = find(x), t2 = find(y);
	if (t1 != t2)
	{
		f[t2] = t1;
		num[t1] += num[t2];//合并集合同时合并集合的个数
	}
}

int main()
{
	while (~scanf("%d%d", &n, &m) && (n || m))
	{
		int t, u, v;
		init();
		for (int i = 0; i < m; i++)
		{
			scanf("%d", &t);
			if (t > 0)
			{
				scanf("%d", &u);
				for (int i = 0; i < t - 1; i++)
				{
					scanf("%d", &v);
					merge(u, v);
				}
			}
		}
		int ans = 0;
		ans = num[find(0)];
		printf("%d\n", ans);
	}
	return 0;
}

你可能感兴趣的:(并查集)