简单并查集的应用;
题目大意:
有一些简单化合物,每个化合物由两种元素组成,将这些化合物装车,如果车上存在k个简单化合物,正好包含k种元素,那么将组成一个易爆化合物;判断有多少化合物不能装车;
题目分析:
每种元素看成一个顶点,则一个简单化合物就是一条边;
图一所示化合物就是由元素A,B组成的边;(为了描述的方便,我将点放大为一个圆)
如果整个图存在环的时候,组成环的边对应的化合物是危险的(即k个简单化合物,正好包含k种元素)反之则是安全的;
如图所示,有三种化合物,A-B B-C C-A 满足成环要求;对应3中化合物包含三种元素;
使用并查集维护图的联通分量集合,每次得到一个简单化合物(x,y)时,检查x和y是否在同一个集合,如果是,则拒接装车,反之则接受;
#include <cstdio>
using namespace std;
const int maxn = 100000+10;
int p[maxn];
void Init(){
for(int i = 0; i < maxn; ++i)
p[i] = i;
}
int Find(int x){
return x == p[x] ? x : p[x] = Find(p[x]);
}
void Union(int x, int y){
int xRoot = Find(x);
int yRoot = Find(y);
p[xRoot] = yRoot;
}
int main()
{
int x, y, ans = 0;
Init();
while(scanf("%d", &x) != EOF){
if(x == -1){
printf("%d\n", ans);
ans = 0;
Init();
continue;
}
scanf("%d", &y);
if(Find(x) != Find(y))
Union(x, y); // 注意不是p[x] = y;(可以思考为什么);
else
ans++;
}
return 0;
}