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 }

 

你可能感兴趣的:(life)