很经典的并查集题目,一开始我们或许觉得无从下手,但是仔细观察可以发现,他的规定很有意思: 如果存在k个化合物,正好包含k种元素 。似乎不能简单的判断所有元素种类是否在一个集合中 。但是如果我们把每个元素看成顶点,则一个简单化合物就是一条边, 不难发现,当整个图存在环的时候,组成环的边对应的化合物恰好是危险的。
所以就像最小生成树算法一样维护图的联通分量就行了。
细节参见代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5;
const int INF = 1000000000;
int k,id,a,cnt,b,p[maxn];
struct Edge{
int a,b;
Edge(int a=0,int b=0):a(a), b(b) {}
}c[maxn];
int findset(int x) { return p[x] == x ? x : p[x] = findset(p[x]); }
int main() {
while(~scanf("%d%d",&a,&b)) {
cnt = 0;
int max_id = max(a,b), ans = 0;
c[cnt++] = Edge(a,b);
while(scanf("%d",&a)) { //输入
if(a == -1) break;
scanf("%d",&b);
max_id = max(max_id,max(a,b));
c[cnt++] = Edge(a,b);
}
for(int i = 1; i <= max_id; i++) p[i] = i;//初始化并查集
for(int i=0;i<cnt;i++) { //solve
int x = findset(c[i].a), y = findset(c[i].b);
if(x != y) p[x] = y;
else ans++;
}
printf("%d\n",ans);
}
return 0;
}