hdu1829 A Bug's Life

http://acm.hdu.edu.cn/showproblem.php?pid=1829

并查集,二分图识别

如果A喜欢B,不能直接判断A,B的性别,但是可以知道,A喜欢的人和B是同性的(一个集合)。

不直接合并A,B所在集合,而间接合并A喜欢的人所在集合 与 B所在集合,使问题得到简化。

 

建立一个like数组,储存A喜欢的一个人为like[A](任意一个都可以),

1.初始化:

开始让每个人喜欢自己,like[i] = i;

在执行合并操作(3)之前,如果A,B双方中还有喜欢自己的,则调整为喜欢对方,like[A] = B, like[B] = A;

2.查询操作:

如果A和B在一个集合中,则AB属于同性恋

3.合并操作:

把A喜欢的人所在集合(find(like[A]))与 B所在集合(find(B)) 合并

把B喜欢的人所在集合(find(like[B]))与 A所在集合(find(A)) 合并

 

 1 #include <stdio.h>
 2 #define N 2013
 3 
 4 int n, m, f[N], l[N];
 5 //f-->father, l-->like
 6 
 7 int find(int x)
 8 {
 9     return x-f[x]? f[x]=find(f[x]): x;
10 }
11 
12 int merge(int x, int y)
13 {
14     int r1, r2;//r-->root
15     r1 = find(x), r2 = find(y);
16     if(r1 != r2)
17     {
18         if(l[x] == x)
19         {
20             l[x] = y;
21         }
22         if(l[y] == y)
23         {
24             l[y] = x;
25         }
26         f[find(l[x])] = r2;
27         f[find(l[y])] = r1;
28         return 0;
29     }
30     return 1;
31 }
32 
33 int main()
34 {
35     int t, cases, i, a, b, flag;
36     scanf("%d", &t);
37     for(cases=1; cases<=t; cases++)
38     {
39         scanf("%d%d", &n, &m);
40         for(i=1; i<=n; i++)
41         {
42             f[i] = l[i] = i;
43         }
44         flag = 0;
45         for(i=1; i<=m; i++)
46         {
47             scanf("%d%d", &a, &b);
48             if(!flag && merge(a, b))
49             {
50                 flag = 1;
51             }
52         }
53         printf("Scenario #%d:\n", cases);
54         printf(flag? "S": "No s");
55         printf("uspicious bugs found!\n\n");
56     }
57     return 0;
58 }

 

posted @ 2013-01-15 15:28  Yuan1991  阅读(158)  评论(0编辑  收藏  举报