POJ 2492 A Bug's Life 并查集的应用

题意:有n只虫子,每次给出一对互为异性的虫子的编号,输出是否存在冲突。

思路:用并查集,每次输入一对虫子后就先判定一下。如果两者父亲相同,则说明关系已确定,再看性别是否相同,如果相同则有冲突。否则就将两只虫子并入一个集合。

而性别则是用一个gender数组来维护,每个虫子的gender的值为0或者1。

0表示该虫子的性别与父亲结点的性别相同。

1表示该虫子的性别与父亲结点的性别不同。

这题和poj1703本质上是一样的。1703的题解请点传送门

另外还有一个疑惑,本题输入量巨大,我用输入加速后反而比用scanf要慢得多,弄不明白为什么。。有知道的大神欢迎来给解答一下。

 1 #include<stdio.h>
 2 #define maxn 2010
 3 int father[maxn], gender[maxn];
 4 int Find(int x)
 5 {
 6     if (father[x] != x)
 7     {
 8         int t = father[x];
 9         father[x] = Find(father[x]);
10         gender[x] = (gender[x] + gender[t]) % 2;
11     }
12     return father[x];
13 }
14 void Merge(int x,int y)
15 {
16     int fx = Find(x);
17     int fy = Find(y);
18     father[fx] = fy;
19     if (gender[y] == 0)
20         gender[fx] = 1 ^ gender[x];
21     else gender[fx] = gender[x];
22 }
23 int main()
24 {
25     int t;
26     int cas = 1;
27     //freopen("data.in", "r", stdin);
28     scanf("%d",&t);
29     while (t--)
30     {
31         int n, m;
32         scanf("%d%d",&n,&m);
33         for (int i = 1; i <= n; i++)
34         {
35             father[i] = i;
36             gender[i] = 0;
37         }
38         int ok = 1;
39         while (m--)
40         {
41             int a, b;
42             scanf("%d%d",&a,&b);
43             if (!ok) continue;
44             if (Find(a) != Find(b))
45                 Merge(a, b);
46             else if(gender[a] == gender[b])
47                 ok = 0;
48         }
49         if (ok) printf("Scenario #%d:\nNo suspicious bugs found!\n\n", cas++);
50         else printf("Scenario #%d:\nSuspicious bugs found!\n\n", cas++);
51     }
52     return 0;
53 }

 

posted @ 2013-08-03 18:46  fenshen371  阅读(186)  评论(0编辑  收藏  举报