并查集的高级使用
加了一个r【】来判断与根节点的关系
find()
如果 a 和 b 的关系是 r1, b 和 c 的关系是 r2,
那么 a 和 c 的关系就是 (r1+r2)%2
Union()
联合时,使得 p[fx] = fy; 同时也要寻找 fx 与 fy 的关系。关系为:(r[x]+r[y]+1)%2
代码如下
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+7;
int p[maxn],r[maxn]; //0表示为1类,1为不同的类
int Find(int x)
{
if(x==p[x]) return x;
int t=p[x];
p[x]=Find(p[x]);
r[x]=(r[x]+r[t])%2;
return p[x];
}
void Union(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
p[fx]=fy;
r[fx]=(r[x]+r[y]+1)%2;
}
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n,m,a,b;
char s;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
p[i]=i; r[i]=0;
}
for(int i=0;i<m;i++){
getchar();
scanf("%c%d%d",&s,&a,&b);
if(s=='D'){
Union(a,b);
}
else if(s=='A'){
if(Find(a)==Find(b)){
if(r[a]!=r[b]) printf("In different gangs.\n");
else printf("In the same gang.\n");
}
else printf("Not sure yet.\n");
}
}
}
}
做完食物链,自己又重新写了一遍
代码如下
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
int p;
int r;
}a[100007];
int Find(int x)
{
if(x==a[x].p) return x;
int temp=a[x].p;
a[x].p=Find(temp);
a[x].r=(a[x].r+a[temp].r)%2;
return a[x].p;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
a[i].p=i;
a[i].r=0;
}
char s; int A,B;
for(int i=0;i<m;i++){
cin>>s;
scanf("%d%d",&A,&B);
int root1=Find(A);
int root2=Find(B);
if(s=='A') {
if(root1!=root2) {
printf("Not sure yet.\n");
}
else{
if(a[A].r==a[B].r) {
printf("In the same gang.\n");
}
else{
printf("In different gangs.\n");
}
}
}
else{
a[root2].p=root1;
a[root2].r=(a[A].r+1+a[B].r)%2;
}
}
}
}