这道题目的描述我感觉还是抄啸爷的吧,这个描述太逗了啊。
题意:某城市存在蛇帮和龙帮两大帮派(话说名字还能再挫一点点吗. . . )。在某一次像东莞这样的大规模的扫黄打非中,警察抓住了 n 个人,但是不缺定他们分别属于哪个帮派。现在给你一些条件,然后让你判断两个人是否属于同一个帮派。
这是一道关系并查集的题目啊,第一次做。啸爷很耐心的讲解了思路。过程很好理解啊。
就是这个并查集需要保存一下他自己与父亲节点的关系,0代表不是一伙,1代表是一伙的。然后在向跟回溯的时候找到这个节点和父亲节点的关系,如果相同r就 不改变,否则就改变。一直找到根节点判断节点和根节点的关系。比较一下就知道是否是一个帮派了啊。因为除了0,就是1。
啸爷的解释:
关系并查集的合并:
当不属于同一棵树的两个点 u , v确定关系时,要将两棵树进行合并。
仍以此题为例:
设ru,rv分别为u,v的跟节点,wu,wv分别表示u,v与跟节点的关系,w[]为节点与父节点的关系。
当wu == wv时,则表示ru和rv属于不同帮派(因为此题中,每次确定关系均为不属于同一帮派), 则w[ru] = 1,fa[ru] = rv;
当wu != wv时,则表示ru和rv属于同一帮派 , 则w[ru] = 0,fa[ru] = rv;
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 27932 | Accepted: 8521 |
Description
Assume N (N <= 10^5) criminals are currently in Tadu City, numbered from 1 to N. And of course, at least one of them belongs to Gang Dragon, and the same for Gang Snake. You will be given M (M <= 10^5) messages in sequence, which are in the following two kinds:
1. D [a] [b]
where [a] and [b] are the numbers of two criminals, and they belong to different gangs.
2. A [a] [b]
where [a] and [b] are the numbers of two criminals. This requires you to decide whether a and b belong to a same gang.
Input
Output
Sample Input
1 5 5 A 1 2 D 1 2 A 1 2 D 2 4 A 1 4
#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
#define eps 1e-7
#define M 10001000
#define LL __int64
//#define LL long long
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
const int maxn = 101000;
using namespace std;
int f[maxn];
int w[maxn];
int r;
int _find(int x)
{
int t = x;
r = 0;
while(x != f[x])
{
if(w[x])
{
if(r == 1)
r = 0;
else
r = 1;
}
x = f[x];
}
f[t] = x;
w[t] = r;
return x;
}
int main()
{
int t;
cin >>t;
int n, m;
while(t--)
{
scanf("%d %d",&n,&m);
char str;
for(int i = 0; i <= n; i++)
{
f[i] = i;
w[i] = 0;
}
while(m--)
{
scanf("%*c%c",&str);
int x, y;
if(str == 'A')
{
scanf("%d %d",&x, &y);
int xx = _find(x);
int r1 = r;
int yy = _find(y);
int r2 = r;
if(xx != yy)
printf("Not sure yet.\n");
else
{
if(r1 == r2)
printf("In the same gang.\n");
else
printf("In different gangs.\n");
}
}
else
{
scanf("%d %d",&x, &y);
int xx = _find(x);
int r1 = r;
int yy = _find(y);
int r2 = r;
f[xx] = yy;
if(r1 == r2)
w[xx] = 1;
else
w[xx] = 0;
}
}
}
return 0;
}