[POJ1703]Find them, Catch them(并查集)

传送门

1.开两个并查集 f[x] 表示 x 的同类 f[x + n] 表示 x 的敌人

——代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #define N 200001
 4
 5 int T, n, m;
 6 int f[N];
 7
 8 inline int read()
 9 {
10     int x = 0, f = 1;
11     char ch = getchar();
12     for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
13     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
14     return x * f;
15 }
16
17 inline int find(int x)
18 {
19     return x == f[x] ? x : f[x] = find(f[x]);
20 }
21
22 inline void connect(int x, int y)
23 {
24     x = find(x);
25     y = find(y);
26     f[x] = y;
27 }
28
29 int main()
30 {
31     int i, j, x, y;
32     char s[1];
33     T = read();
34     while(T--)
35     {
36         n = read();
37         m = read();
38         for(i = 1; i <= (n << 1); i++) f[i] = i;
39         for(i = 1; i <= m; i++)
40         {
41             scanf("%s", s);
42             x = read();
43             y = read();
44             if(s[0] == ‘A‘)
45             {
46                 if(find(x) == find(y)) puts("In the same gang.");
47                 else if(find(x) == find(y + n) || find(y) == find(x + n)) puts("In different gangs.");
48                 else puts("Not sure yet.");
49             }
50             else
51             {
52                 connect(x, y + n);
53                 connect(y, x + n);
54             }
55         }
56     }
57 } 

2.带权并查集

——代码

 1 #include <cstdio>
 2 #include <iostream>
 3 #define N 1000001
 4
 5 int T, n, m;
 6 int f[N], d[N];
 7
 8 inline int read()
 9 {
10     int x = 0, f = 1;
11     char ch = getchar();
12     for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;
13     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;
14     return x * f;
15 }
16
17 inline int find(int x)
18 {
19     if(x ^ f[x])
20     {
21         int fx = f[x];
22         f[x] = find(f[x]);
23         d[x] = (d[x] + d[fx]) % 2;
24     }
25     return f[x];
26 }
27
28 inline void connect(int x, int y)
29 {
30     int fx = find(x), fy = find(y);
31     d[fx] = (d[y] + 1 - d[x]) % 2;
32     f[fx] = f[y];
33 }
34
35 int main()
36 {
37     int i, x, y;
38     char s[1];
39     T = read();
40     while(T--)
41     {
42         n = read();
43         m = read();
44         for(i = 1; i <= n; i++) f[i] = i, d[i] = 0;
45         for(i = 1; i <= m; i++)
46         {
47             scanf("%s", s);
48             x = read();
49             y = read();
50             if(s[0] == ‘D‘) connect(x, y);
51             else
52             {
53                 if(find(x) ^ find(y)) puts("Not sure yet.");
54                 else if(d[x] == d[y]) puts("In the same gang.");
55                 else puts("In different gangs.");
56             }
57         }
58     }
59     return 0;
60 }

时间: 2024-10-12 13:18:51

[POJ1703]Find them, Catch them(并查集)的相关文章

poj1703(Find them, Catch them)并查集

Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal belongs to. The present

POJ1703 Find them, Catch them 并查集 好题 有坑点

Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon and Gang Snake. However, the police first needs to identify which gang a criminal belongs to. The present

POJ 2236 Wireless Network ||POJ 1703 Find them, Catch them 并查集

POJ 2236 Wireless Network http://poj.org/problem?id=2236 题目大意: 给你N台损坏的电脑坐标,这些电脑只能与不超过距离d的电脑通信,但如果x和y均能C通信,则x和y可以通信.现在给出若干个操作, O p 代表修复编号为p的电脑 S p q代表询问p和q是不是能通信. 思路: 并查集即可.. 如果修复了一台电脑,则把与它相连距离不超过d的且修复了的放在一个集合里面. #include<cstdio> #include<cstring&

POJ 1703 Find them, catch them (并查集)

题目:Find them,Catch them 刚开始以为是最基本的并查集,无限超时. 这个特殊之处,就是可能有多个集合. 比如输入D 1 2  D 3 4 D 5 6...这就至少有3个集合了.并且任意2个集合之间成员的敌我关系不明. 这里每个集合里面的成员关系要记录,他们在一个集合里,只是因为他们关系明确,敌人或者朋友. 千万不要简单的认为成朋友在一个集合,敌人在另外一个集合,分成2个集合.因为题目说只有2个匪帮,很容易进入这个误区. 我们只要记录一个成员和自己父亲的敌我关系和建树就可以了.

poj1073--Find them, Catch them(并查集应用)

Find them, Catch them Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 32073   Accepted: 9890 Description The police office in Tadu City decides to say ends to the chaos, as launch actions to root up the TWO gangs in the city, Gang Dragon

北大ACM1703——Find them, Catch them~~并查集

题目的意思是:在一个城市,有两个犯罪团伙.输入N(人的个数)和M(信息的个数).后面M条信息是一个字母加上两个数字i和j,如果字母为D,则说明i和j属于不同的犯罪团伙,如果字母是A,则要你判断i和j的关系,属于同一个还是属于不同的还是不确定. 一开始,觉得这个题目计较棘手,属于D的情况下,是属于不同的犯罪团伙,不知道如何来解决. 后来想到了之前看到的一题,POJ1182食物链,判断有多少条信息是错的.有三个并查集来判断动物的关系. 所以这一题,我们可以用两个并查集来判断.N最大为10^5,所以并

POJ No1703 Find them, Catch them 并查集

题目链接:http://poj.org/problem?id=1703 题意:两个坏蛋属于不同的组织,给出两个坏蛋判定是否一个组织. 题解:已知每次输入的两个帮派人员 x, y; 合并 (x, y + N), (x + N, y).判定时,如果 (x, y) 属于同一个 根,就是同一个组织,(x, y+N) 属于同一个根,则说明是不同组织.不确定则无解. #include <iostream> using namespace std; const int maxn = 100000*2 + 2

poj1703 Find them,Catch them 【并查集】

做过一些的带权并查集,再来做所谓的"种类并查集",发现好像就顿悟了. 种类并查集与带权并查集实质上的差别并不大, 关键的区别就是种类并查集只是带权并查集再弄个%取余操作而已,然后余数就表示他属于哪个种类. 这题只有两个种类,也就是只有0和1两种, 对于两个不同的种类,那么之间的权值是相差1的,所以按照带权并查集的方法做加上1,然后取余2即可. #include<cstdio> const int N = 100005; int n, m, f[N], rank[N]; in

poj1703 Find them, Catch them(带权并查集)

题目链接 http://poj.org/problem?id=1703 题意 有两个帮派:龙帮和蛇帮,两个帮派共有n个人(编号1~n),输入m组数据,每组数据为D [a][b]或A [a][b],D[a][b]表示a,b属于不同的帮派,A [a][b]则让我们判断a,b是否属于一个帮派,根据判断的结果进行相应的输出. 思路 这题和poj2492很像,使用并查集解决,方法我已在poj2492的题解中写出,这里不再赘述. 代码 1 #include <cstdio> 2 using namespa

Find them, Catch them.(POJ-1703)(并查集)

本题也是一道经典的并查集题目,只不过并不是直来直去的,因为需要维护两组关系:同一伙.不是同一伙. 那要怎么办呢,一开始我用了vector来保存对立面,建立两个并查集,结果很自然是超时的,因为循环了太多次. 之后看别人的题解,感觉有点复杂,看的不是很明白,只有一篇给出了一个简单的方法,然后我又重新看了食物链那道题,发现本题就是那道题的改编,可以使用相同的方法来维护多组关系. 就像食物链那道题一样,对每个人创建两个元素:i和i+n.用3*n个元素来建立并查集,这个并查集可以维护如下信息: 如果x和y