这题真的是并查集的经典题目= =
题意是给出n个人,然后给出若干的操作
1表示让a,b成为朋友,若与前面的朋友敌人关系相矛盾,输出-1
2表示让a,b成为敌人,若与前面的朋友敌人关系矛盾输出-1
3判断a,b是否是朋友,是输出1,不是输出0
4判断a,b是否是敌人,是的话输出1,不是的话输出-1
首先ab朋友关系部成立是他们刚好属于敌对的阵营。同理,a,b的敌对关系不成立的条件是他们属于同一个阵营
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int N=10100; int p[N],q[N],pu,pv,qu,qv; int find(int x) { return p[x]==x?x:find(p[x]); } void fun1() { if(pu==qv&&pv==qu)//a,b属于敌对阵营 { printf("-1 "); } else { if(qu==-1&&qv==-1)//a,b,没有敌人 p[pu]=pv;合并关系 else if(qu==-1)//a没有敌人 p[pu]=pv; else if(qv==-1)//b没有敌人 p[pv]=pu; else//a,b有敌人,但不是敌对阵营,要合并a,b的敌人让他们变成朋友 { p[pu]=pv; p[qu]=qv; } } } void fun2() { if(pu==pv)//a,b属于同一个阵营,不符合要求 { printf("-1 "); } else { q[pu]=pv;//把a,b分别合并在他们的敌对阵营 q[pv]=pu; if(qu!=-1) p[qu]=pv; if(qv!=-1) p[qv]=pu; //把a,b的敌人合并成朋友关系 } } void fun3() { if(pu==pv) printf("1 "); else printf("0 "); } void fun4() { if(pu==qv&&pv==qu) printf("1 "); else printf("0 "); } int main() { int n; scanf("%d",&n); for(int i=0;i<=n;i++) { p[i]=i; q[i]=-1; } int a,b,c; while(scanf("%d %d %d",&c,&a,&b)!=EOF) { if(!a&&!b&&!c) break; pu=find(a); pv=find(b); qu=q[pu]; if(qu!=-1) qu=find(qu); qv=q[pv]; if(qv!=-1) qv=find(qv); if(c==1) fun1(); else if(c==2) fun2(); else if(c==3) fun3(); else fun4(); } return 0; }