本篇是刘汝佳《算法竞赛入门经典——训练指南》的读书笔记。
知识点: 并查集
解题思路:
将每种元素看成一个点,而每种化合物看成是由两种元素(即两个点组成的一条边),以此建图。如果加入某一条边后会出现环(即\(k\)条边(化合物),\(k\)个点(元素)),那么我们就不将这条边加入图中,即\(ans+1\).
用并查集来维护这个图,如果一条边的两个点本来就相连(即其根节点相同),那么就说明加入这条边后会出现环。
AC代码:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 const int maxn = 1e5+10; 5 6 int par[maxn]; 7 void init(){ 8 for(int i=0;i<maxn;i++) 9 par[i]=i; 10 } 11 int finds(int x){ 12 if(par[x]==x) return x; 13 return par[x]=finds(par[x]); 14 } 15 int main(){ 16 int a,b; 17 int ans=0; 18 init(); 19 while(scanf("%d",&a)==1){ 20 if(a==-1){ 21 printf("%d\n",ans); 22 ans=0; 23 init(); 24 continue; 25 } 26 scanf("%d",&b); 27 a=finds(a),b=finds(b); 28 if(a==b) ans++; 29 else par[a]=b; 30 } 31 return 0; 32 }