poj(1703)
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 26992 | Accepted: 8188 |
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代表帮派成员编号,有m次操作,D[a][b]代表a和b不是一个帮派,A[a][b]询问a和b是什么关系,即:关系不确定,在一个帮派,不再一个帮派。
分析:并查集,用一个辅助数组pre[],(pre[a]=b||pre[b]=a)代表a的敌人是b,b的敌人是a,输入D的时候有四种情况构造并查集
(1)若pre[a]==-1&&pre[b]==-1,则:pre[a]=b;pre[b]=a;
(2)若pre[a]==-1&&pre[b]!=-1:则:pre[a]=b;make(a,pre[b]):把b的敌人和a并在一棵树里,即为朋友;
(3)若pre[a]1=-1&&pre[b]==-1;则:同上;
(4)若pre[a]!!=-1&&pre[b]!=-1:则:make(a,pre[b]),make(pre[a],b);
对于每次A询问:
若finde(a)==finde(b)一定是朋友;
否则有两种情况,要么不确定,要么是敌人;
当:finde(pre[a])==finde(b)即:a的老大的敌人与b的老大是朋友,则a和b一定是敌人
否则是不确定的
程序:
#include"stdio.h" #include"string.h" #define M 100004 int f[M]; int pre[M]; int finde(int x) { if(x!=f[x]) f[x]=finde(f[x]); return f[x]; } void make(int a,int b) { int x=finde(a); int y=finde(b); if(x!=y) f[x]=y; } int main() { int w,n,m,a,b,i; char ch[2]; scanf("%d",&w); while(w--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) f[i]=i; memset(pre,-1,sizeof(pre)); while(m--) { scanf("%s%d%d",ch,&a,&b); if(ch[0]=='D') { if(pre[a]==-1&&pre[b]==-1) { pre[a]=b; pre[b]=a; } else if(pre[a]==-1&&pre[b]!=-1) { make(a,pre[b]); pre[a]=b; } else if(pre[a]!=-1&&pre[b]==-1) { make(b,pre[a]); pre[b]=a; } else { make(pre[a],b); make(pre[b],a); } } else { if(finde(a)==finde(b)) printf("In the same gang.\n"); else { if(finde(pre[a])==finde(b)) printf("In different gangs.\n"); else printf("Not sure yet.\n"); } } } } return 0; }