UVA 1160 X-Plosives

题意是一次装入物品,物品由两种元素组成,当遇到即将装入的物品与已经装入的物品形成k个物品,k种元素,跳过该物品的装入。可以将每种元素看成顶点,物品看成一条边。这样问题就转化为利用并查集求环的情况。

算法竞赛训练指南中的代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <climits>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cmath>
 7 #include <vector>
 8 #include <queue>
 9 #include <algorithm>
10 #define esp 1e-6
11 #define pb push_back
12 #define in  freopen("in.txt", "r", stdin);
13 #define out freopen("out.txt", "w", stdout);
14 #define print(a) printf("%d\n",(a));
15 #define bug puts("********))))))");
16 #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
17 #define inf 0x0f0f0f0f
18 using namespace std;
19 typedef long long  LL;
20 typedef vector<int> VI;
21 typedef pair<int, int> pii;
22 typedef vector<pii,int> VII;
23 typedef vector<int>:: iterator IT;
24 
25 #define N (int)(1e5+100)
26 int pa[N], rank[N];
27 void init(void)
28 {
29     for(int i = 0; i < N; i++)
30         pa[i] = i;
31     memset(rank, 0, sizeof(rank));
32 }
33 void merge(int x, int y)
34 {
35     if(rank[x] > rank[y])
36         pa[y] = x;
37     else {
38         pa[x] = y;
39         if(rank[x] == rank[y])
40             rank[y]++;
41     }
42 }
43 int findset(int x)
44 {
45     return  (pa[x] == x) ? x: pa[x] = findset(pa[x]);
46 }
47 int main(void)
48 {
49 int x, y;
50     while(~scanf("%d", &x))
51     {
52         int cnt = 0;
53         init();
54         while(x != -1)
55         {
56             scanf("%d", &y);
57             x = findset(x), y = findset(y);
58             if(x == y)
59                 cnt++;
60                 else merge(x, y);
61             scanf("%d", &x);
62         }
63         printf("%d\n", cnt);
64     }
65     return 0;
66 }

 

你可能感兴趣的:(uva)