http://poj.org/problem?id=1703
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 31589 | Accepted: 9739 |
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
Sample Output
Not sure yet. In different gangs. In the same gang.
题目大意:在这个城市里有两个黑帮团伙,现在给出N个人,问任意两个人他们是否在同一个团伙
输入D x y代表x于y不在一个团伙里
输入A x y要输出x与y是否在同一团伙或者不确定他们在同一个团伙里
用图解释一下并查集的向量偏移
加入1和2是敌人,2和3是敌人,用mark[]标记0和1,更新如下;
a=1;b=2 ==> x=1,y=2; ==> f[1]=2;
Mark[1]=(mark[1]+mark[2]+1)%2=1;
a=2,b=3 ==> x=2,y=3; ==> f[2]=3;
Mark[2]=(mark[2]+mark[3]+1)%2=1;
现在找1和3是什么关系;
递归过程:
x=1;f[x]=2;x!=f[x]; t=f[x]=2 ==<f[x]=finde(f[x])>==>
x=2;f[x]=3;x!=f[x], t=f[x]=3 ==<f[x]=finde(f[x])>==>
x=3;f[x]=3; return f[x]; <==f[x]=finde(f[x])==
Mark[2]=(mark[2]+mark[t=3])%2=1; return f[x]; <==f[x]=finde(f[x])==
Mark[1]=(mark[1]+mark[t=2])%2=0; return f[x];
更新完;
发现mark[1]==mark[3];就是一类;
程序:
#include"stdio.h"
#include"string.h"
#include"queue"
#include"stack"
#include"math.h"
#include"iostream"
#define M 100005
#define inf 100000000
#define mod 10007
#define eps 1e-10
using namespace std;
int f[M],mark[M];
int finde(int x)
{
if(x!=f[x])
{
int t=f[x];
f[x]=finde(f[x]);
mark[x]=(mark[x]+mark[t])%2;
}
return f[x];
}
void make(int a,int b)
{
int x=finde(a);
int y=finde(b);
if(x!=y)
{
f[x]=y;
mark[x]=(mark[a]+mark[b]+1)%2;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n,m,i;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
f[i]=i;
memset(mark,0,sizeof(mark));
while(m--)
{
int a,b;
char str[3];
scanf("%s%d%d",str,&a,&b);
if(str[0]=='D')
{
make(a,b);
}
else
{
int x=finde(a);
int y=finde(b);
if(x!=y)
printf("Not sure yet.\n");
else if(mark[a]==mark[b])
printf("In the same gang.\n");
else
printf("In different gangs.\n");
}
}
}
return 0;
}