poj1611 简单并查集

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 30100
int father[N] = { 0 };
int rank1[N] = { 0 }, num[N] = { 0 };
int find(int x)//并查集的find找老子
{
	if (x != father[x]) 
	father[x] = find(father[x]);
	return father[x];
}
void unionset(int x, int y)//并查集的并
{
	x = find(x);
	y = find(y);
	if (x == y)return;
	if (rank1[x]>rank1[y])//rank为数的深度
	{
		father[y] = x;//大树作为小树的父亲
		num[x] += num[y];
	}
	else
	{
		if (rank1[x] == rank1[y])
		{
			rank1[y]++;//来一次了所以树的深度加一次
		}
		father[x] = y;
		num[y] += num[x];
	}
}
int main()
{
	int n, m, i, j, k, t, pos0, t0, x, y;
	while (1)
	{
		cin >> n >> m;
		if (n == 0 && m == 0)break;
		memset(rank1, 0, sizeof(rank1));
		for (i = 0; i<n; i++)
		{
			father[i] = i;
			num[i] = 1; 
		}
		for (i = 0; i<m; i++)
		{
			cin >> k >> t0;
			for (j = 1; j<k; j++)
			{
				 cin>>t;
				x = find(t0);
				y = find(t);
				unionset(x, y);
			}
		}
		pos0 = find(0);
	  cout<< num[pos0]<<endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值