题意:
有一些简单化合物,每个化合物都由两种元素组成的,你是一个装箱工人、从实验员那里按照顺序把一些简单化合物装到车上,但这里存在安全隐患:如果车上存在K个简单化合物,正好包含K种元素,那么他们就会组成一个容易爆炸的混合物,为了安全起见,每当你拿到一个化合物时,如果它已经和已装车的化合物形成了易爆混合物,你就应该拒绝装车,否则就应该装车,输出你拒绝了多少个混合物。
思路:
一种化合物由两种元素组成,所以我们就可以把每个元素看成一个点,那么一个简单化合物就是一条边。当图出现环的时侯,组成环的边对应的化合物就是比较危险的,否则就是安全的。。所以我们可以用并查集来把每次进来的化合物的两个元素看成点,加入集合之中,每次得到一个化合物判断是否使整个图形成了环,如果是 就拒绝,否则就接受。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cmath> 6 #include <cctype> 7 #include <algorithm> 8 using namespace std; 9 const int MAXN = 1e5 + 3; 10 int pre[MAXN]; 11 int Find(int x) 12 { 13 int r = x; 14 while(pre[r] != r) 15 { 16 r = pre[r]; 17 } 18 int i = x,j; 19 while(pre[i] != r) 20 { 21 j = i; 22 i = pre[i]; 23 pre[j] = r; 24 } 25 return r; 26 } 27 28 void Mix(int a,int b) 29 { 30 int x = Find(a); 31 int y = Find(b); 32 if(x > y) 33 { 34 pre[x] = y; 35 } 36 if(x < y) 37 { 38 pre[y] = x; 39 } 40 } 41 42 43 void Mst() 44 { 45 for(int i = 1; i <= MAXN; i++) 46 { 47 pre[i] = i; 48 } 49 } 50 51 int main() 52 { 53 //freopen("in.txt","r",stdin); 54 //freopen("out.txt","w",stdout); 55 int m,n; 56 int ans = 0; 57 Mst(); 58 while(~scanf("%d",&n)) 59 { 60 if(n == -1) 61 { 62 cout << ans <<endl; 63 ans = 0; 64 Mst(); 65 continue; 66 } 67 scanf("%d",&m); 68 int fx = Find(n); 69 int fy = Find(m); 70 if(fx == fy) ans++; //形成了环 71 else Mix(n,m); 72 } 73 return 0; 74 }