UVA 1160 并查集

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3601

题目大意:给你很多堆元素组合,每一堆组合有两个元素,当堆数等于元素种类数的时候,就会发生爆炸。你要把这些组合放到一个屋子里面,如果当前选择会发生爆炸,那么就拒绝,否则必须接受。输出拒绝的次数。

思路:这道题的转化还挺巧妙的,我们把每种元素看成一个点,如果这两个元素组合到了一起,我们就画上一条线。于是问题就转化成了:判断一个图是否有环。当两个结点的根结点相同时,再划线必定会有环,这是不合题意的。(题目说了不会有重复的组合出现)这个判断根结点是否相同的操作是不是就是并查集的操作呢~

#include<iostream>
#include<cstdio>
#include<stack>
#include<cmath>
#include<cstring>
#include<queue>
#include<set>
#include<algorithm>
#include<iterator>
#define INF 0x3f3f3f3f
typedef long long ll;
typedef unsigned long long ull;
using namespace std;

					//转换成 图无环问题
const int MAX=100000;
int f[MAX+5];
int cnt=0;

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

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

void Union(int x,int y)
{
	int fx=father(x),fy=father(y);
	if(fx==fy)
		++cnt;
	else
	{
		f[fx]=fy;
	}
}

int main()
{
	int n,m;
	while(~scanf("%d",&n))
	{
		init();
		while(n!=-1)
		{
			scanf("%d",&m);
			Union(n,m);
			scanf("%d",&n);
		}
		printf("%d\n",cnt);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiji333/article/details/86649837