POJ 1703 Find them, Catch them 并查集的应用

题意:城市中有两个帮派,输入中有情报和询问。情报会告知哪两个人是对立帮派中的人。询问会问具体某两个人的关系。

思路:并查集的应用。首先,将每一个情报中的两人加入并查集,在询问时先判断一下两人是否在一个集合中,如果是,则表明两个人的关系已知。

本题还需要判断出两人是不是在同一帮派,这里用一个relation数组来维护每个人与根结点的关系。

0表示该人与根节点为同一个帮派。

1表示该人与根节点为对立帮派。

 

并查集有两个基本操作:find——查找根节点, merge——合并两个集合。

在合并两个集合时,其中一个集合的relation的值要发生变化。在这里只需要改变集合根节点的relation(改变的规则见代码中merge函数,relation改变的规则自己举几个例子就明白了)。

其余点的值在find函数压缩路径时就顺便完成了。relation的状态只有两种(0和1),在压缩路径时的变化规则就是点到根节点的relation=(与父亲结点的relation+父亲结点与根节点的relation)% 2。

 1 #include<stdio.h>

 2 #define maxn 100010

 3 int father[maxn];

 4 bool relation[maxn];

 5 int Find(int x)

 6 {

 7     if (father[x] != x)

 8     {

 9         int t = father[x];

10         father[x] = Find(father[x]);

11         relation[x] = (relation[t] + relation[x]) % 2;

12     }

13     return father[x];

14 }

15 void Merge(int x,int y)

16 {

17     int a = Find(x);

18     int b = Find(y);

19     father[a] = b;

20     if (relation[y] == 0)

21         relation[a] = 1 ^ relation[x];

22     else relation[a] = relation[x];

23 }

24 int main()

25 {

26     int t, n, m;

27     scanf("%d",&t);

28     while (t--)

29     {

30         scanf("%d%d",&n,&m);

31         for (int i = 1; i <= n; i++)

32         {

33             father[i] = i;

34             relation[i] = 0;

35         }

36         char op;

37         int a, b;

38         while (m--)

39         {

40             getchar();

41             scanf("%c",&op);

42             if (op == 'D')

43             {

44                 scanf("%d%d",&a,&b);

45                 Merge(a, b);

46             }

47             else

48             {

49                 scanf("%d%d",&a,&b);

50                 if (Find(a) == Find(b))

51                 {

52                     if (relation[a] == relation[b])

53                         printf("In the same gang.\n");

54                     else

55                         printf("In different gangs.\n");

56                 }

57                 else

58                     printf("Not sure yet.\n");

59             }

60         }

61     }

62     return 0;

63 }

 

 

你可能感兴趣的:(catch)