【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 }

 

    

你可能感兴趣的:(catch)