poj 2492 && 1703

题目:http://poj.org/problem?id=2492

题意:给出一些虫子,然后给出一些关系,每行的两个数 x y 表示 x 和 y 可以交配,问你是否可以在里面找出同性恋

思路:利用并查集记录他们的祖先,需要再用一个数组保存他们属于的种类,1代表一个类,0代表另一个类,在递归找祖先时同时给他们分类。然后询问的时候看他们是不是一个祖先,如果是一个祖先然后看他们是不是同一类,如果是证明他俩是同性恋;如果他们的祖先不相同,那么就要进行合并操作,同时修改一个祖先的类

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <algorithm>
 4 #include <iostream>
 5 #include <string>
 6 #include <sstream>
 7 #include <map>
 8 #define N 2010
 9 #define M 10010
10 #define _clr(a,val) (memset(a,val,sizeof(a)))
11 
12 using namespace std;
13 
14 int f[N];
15 int a[N];
16 int find(int x)
17 {
18     int tem = f[x];
19     if(x != f[x])
20     f[x] = find(f[x]);
21     a[x] = (a[x] + a[tem]) % 2;  // 标记出他所属的类,他的类取决于他自身和他父亲所属的类
22     return f[x];
23 }
24 int main()
25 {
26     int t;
27     int cs = 0;
28     int i,n,m;
29     int x,y;
30     //freopen("data.txt","r",stdin);
31     scanf("%d",&t);
32     while(t--)
33     {
34         scanf("%d%d",&n,&m);
35         for(i = 0; i <= n; i++)
36         {
37             f[i] = i;
38             a[i] = 0;
39         }
40         int flag = 0;
41         for(i = 0; i < m; i++)
42         {
43             scanf("%d%d",&x,&y);
44             if(flag) continue;
45             int root1 = find(x);
46             int root2 = find(y);
47             if(root1 == root2)
48             {
49                 if(a[x] % 2 == a[y] % 2)
50                 {
51                     flag = 1;
52                 }
53             }
54             else
55             {
56                 f[root1] = root2; // 合并
57                 a[root1] = (a[y] - a[x] + 1) % 2;  // 修改一个祖先的类
58             }
59         }
60         printf("Scenario #%d:\n",++cs);
61         if(flag) cout<<"Suspicious bugs found!\n";
62         else cout<<"No suspicious bugs found!\n";
63         if(t) cout<<endl;
64     }
65     return 0;
66 }

题目:http://poj.org/problem?id=1703

题意:给两种操作:D A B 说明 A B不在一间屋子里,A A B 询问 A B 是否在一个屋子里,还是不能确定A  B的关系

思路:跟上一个题一样的思想,如果是 D 则进行合并操作,如果A则判断,具体看代码吧

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <algorithm>
 5 #define N 100010
 6 #define _clr(a,val) (memset(a,val,sizeof(a)))
 7 
 8 using namespace std;
 9 
10 int f[N];
11 int mark[N];
12 int find(int x)
13 {
14     int tem = f[x];
15     if(x != f[x])
16     f[x] = find(f[x]);
17     mark[x] = (mark[x] + mark[tem]) % 2;
18     return f[x];
19 }
20 int main()
21 {
22     int t,i;
23     int n,m;
24     char ch[10];
25     int x,y;
26     //freopen("data.txt","r",stdin);
27     scanf("%d",&t);
28     while(t--)
29     {
30         for(i = 0; i < n; i++)
31         scanf("%d%d",&n,&m);
32         for(i = 1; i <= n; i++)
33         {
34             f[i] = i;
35             mark[i] = 0;
36         }
37         for(int i = 0;i < m; i++)
38         {
39             scanf("%s%d%d",&ch,&x,&y);
40             int root1 = find(x);
41             int root2 = find(y); 
42             if(ch[0] == 'D')  // 如果是D则直接合并
43             {
44                 f[root2] = root1;
45                 mark[root2] = (mark[x] - mark[y] + 1) % 2; // 修改类
46             }
47             else // 如果是A 则判断
48             {
49                 if(root1 != root2)  // 如果根不同,则无法判断关系
50                 printf("Not sure yet.\n");
51                 else if(mark[x] == mark[y])  // 如果所属类相同,则是一个房间
52                 printf("In the same gang.\n");
53                 else printf("In different gangs.\n");
54             }
55         }
56     }
57     return 0;
58 }
原文地址:https://www.cnblogs.com/fxh19911107/p/2622284.html