【POJ 1703 Find them, Catch them】并查集
题目链接:http://poj.org/problem?id=1703
题目大意:
给定m个操作:
D x y:x罪犯和y罪犯不在一个团伙。(总共只有两个团伙)
A x y:询问x和y罪犯的关系
解题思路:
很容易想到是并查集,但最后还是让我纠结了良久。一直MLE。
对于每次的D x y操作,每次不仅要找到两个不同集合标志头进行更新,还要更新a数组,即存储的相对集合的标志头。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn=100005; 9 int f[maxn], a[maxn]; ///a数组表示的是这个集合指向另一个相对的集合 10 11 int find(int x) 12 { 13 if(x==f[x]) return x; 14 return f[x]=find(f[x]); 15 } 16 17 int main() 18 { 19 int T, n, m; 20 cin >> T; 21 while(T--) 22 { 23 cin >> n >> m; 24 for(int i=0; i<=n; i++) 25 f[i]=i, a[i]=0; 26 char ch[2]; 27 int x, y; 28 while(m--) 29 { 30 scanf("%s%d%d",ch,&x,&y); 31 if(ch[0]=='D') 32 { 33 x=find(x); ///注意这里指向两个不同集合的标志头 34 y=find(y); 35 if(!a[x]) a[x]=y; 36 if(!a[y]) a[y]=x; 37 a[x]=find(a[x]);///!!!这里也要注意更新,指向另一集合的标志头 38 a[y]=find(a[y]); 39 f[a[x]]=y; 40 f[a[y]]=x; 41 } 42 else 43 { 44 x=find(x),y=find(y); 45 if(x==y) 46 puts("In the same gang."); 47 else if(find(a[x])==y) 48 puts("In different gangs."); 49 else 50 puts("Not sure yet."); 51 } 52 } 53 } 54 return 0; 55 }