http://poj.org/problem?id=1703
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 31589 | Accepted: 9739 |
Description
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; }