POJ 1703 Find them, Catch them

题意:罪犯有两个帮派,有两种命令,D a b,a,b表示罪犯的编号,这句话表示a和b来自不同的帮派。A a b,a,b表示罪犯的编号,这句话是问你a和b是否来自同一个帮派,可以有三种回答,“目前不确定“,”是“,”不是“。罪犯最多10^5个,命令最多10^5个。

解法:并查集基础题。用一个struct node表示每一个罪犯,node.f表示该罪犯的父亲节点,node.r表示该罪犯与父亲节点对应的罪犯的关系(0表示来自同一个帮派,1表示不同)。然后写find函数注意更新node.r就行。具体见代码吧。

Ps:另外,本题是POJ 1182的简化版,题解见POJ 1182 食物链

tag:并查集

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-11-26 09:19
 4  * File Name: G-POJ-1703.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 
 9 using namespace std;
10 
11 const int maxn = 100005;
12 
13 struct node{
14     int f, r;
15 };
16 
17 char s[10];
18 int n, m;
19 node a[maxn];
20 
21 void init()
22 {
23     for (int i = 0; i < n; ++ i){
24         a[i].f = i;
25         a[i].r = 0;
26     }
27 }
28 
29 int find(int x)
30 {
31     if (x == a[x].f){
32         a[x].r = 0;
33         return x;
34     }
35 
36     int y = a[x].f;
37     a[x].f = find(a[x].f);
38     a[x].r = (a[y].r + a[x].r) % 2;
39     return a[x].f;
40 }
41 
42 void merge(int x, int y)
43 {
44     int t1 = find(x), t2 = find(y);
45     a[t1].f = t2;
46     a[t1].r = (a[y].r + a[x].r + 1) % 2;
47 }
48 
49 int main()
50 {
51     int T;
52     scanf ("%d", &T);
53     while (T --){
54         scanf ("%d%d", &n, &m);
55         init();
56 
57         int x, y;
58         while (m --){
59             scanf ("%s%d%d", s, &x, &y);
60             int t1 = find(x), t2 = find(y);
61             if (s[0] == 'D')
62                 merge(x, y);
63             else{
64                 if (t1 != t2)
65                     printf ("Not sure yet.\n");
66                 else{
67                     if (a[x].r == a[y].r)
68                        printf ("In the same gang.\n"); 
69                     else
70                         printf ("In different gangs.\n");
71                 }
72             }
73         }
74     }
75     return 0;
76 }
View Code

 

posted @ 2013-11-26 09:47  Plumrain  阅读(650)  评论(0编辑  收藏  举报