UVA1160 题解

前置知识

  • 并查集

简单的查找(带路经压缩):

int find(int x){
	return x == fa[x] ? x : fa[x] = find(fa[x]);
    // fa[i] 为并查集的数组
}

查找(这里可以数据小完全不需要用启发式合并):

void merge(int x,int y){
	int f = find(x),t = find(y);
    fa[f] = t;
}

查阅资料可知,只用路径压缩,不用启发式合并的平均时间复杂度为 \(O(\alpha (n))\) ,最坏时间复杂度为 \(O(m \log n)\)

思路

首先可以将每个元素看成点,化合物看成边,因为如果有超过 3 个物品互相形成化合物就会爆炸,所以会爆炸的条件可以看成两个是在同一祖先(在同一集合)中,(如果这两个点有一个祖先的话,合并就会有 3 个物品在一起的)。

每一次都将不在一个集合中两个数合并。

#include<cstdio>
#include<iostream>

using namespace std;

int fa[100010];

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

int main()
{
	int x,y;
	while(scanf("%d",&x) == 1){    \\ 注意输入
		for(int i=1;i<=100010;i++)	fa[i] = i;
		int ans = 0;
		while(x != -1){
			scanf("%d",&y);
			int f = find(x),t = find(y);
			if(f == t)	ans ++;
			else
				fa[f] = t;    // 如果不会爆炸,就合并
			scanf("%d",&x);
		}
		cout<<ans<<endl;
	}
	return 0;
}
posted @ 2021-08-22 12:26  在那遥远的悠穹下  阅读(27)  评论(0编辑  收藏  举报