Find them, Catch them(并查集)

http://poj.org/problem?id=1703

题意:有两个黑帮团伙,共n名团伙成员(不知道属于这两个黑帮中的哪一个)。现在警察有一些信息,每条信息包含2个人的编号,如果给出A a b,则输出a b的关系,即是否属于同一个黑帮;

如果给出D a b,则说明a b属于不同的黑帮。

思路:典型的并查集,只要两者的关系确定了,就将他们放入同一个集合内,而另外增加一个表示关系的数组link[]来表示该节点与其父亲的关系,0表示同一类,1表示不同团伙。初始时集合只有自己一个元素,link[] 初始为0。

第一次用c++的输入输出,TLE了。。改成C的就A了。

TLE 代码:

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 const int N=100005;
 5 int f[N],link[N];
 6 int n,m;
 7 
 8 int find(int x)
 9 {
10     int t = f[x];
11     if (x!=f[x])
12         f[x] = find(f[x]);
13     link[x] = (link[x]==link[t] ? 0 : 1);
14     return f[x];
15 
16 }
17 void merge(int x,int y,int fu,int fv)
18 {
19     f[fu] = fv;
20     link[fu] = (link[x]==link[y] ? 1 : 0);
21 }
22 void init()
23 {
24     for (int i = 0; i <= n; i ++)
25     {
26         f[i] = i;
27         link[i] = 0;
28     }
29 
30 }
31 int main()
32 {
33     int T;
34     cin>>T;
35     while(T--)
36     {
37 
38         cin>>n>>m;
39         init();
40         while(m--)
41         {
42             int u,v;
43             char s;
44             cin>>s>>u>>v;
45             int fu = find(u);
46             int fv = find(v);
47             if (s=='A')
48             {
49                 if(fu!=fv)
50                 {
51                     cout<<"Not sure yet."<<endl;
52                     continue;
53                 }
54                 if (link[u]==link[v])
55                 {
56                     cout<<"In the same gang."<<endl;
57                     continue;
58                 }
59                 cout<<"In different gangs."<<endl;
60                 continue;
61             }
62             if (s=='D')
63             {
64                 if (fu!=fv)
65                     merge(u,v,fu,fv);
66             }
67 
68         }
69     }
70     return 0;
71 }
View Code

AC代码:

 1 #include <stdio.h>
 2 const int N=100005;
 3 int f[N],link[N];
 4 int n,m;
 5 
 6 int find(int x)
 7 {
 8     int t = f[x];
 9     if (x!=f[x])
10         f[x] = find(f[x]);
11     link[x] = (link[x]==link[t] ? 0 : 1);
12     return f[x];
13 
14 }
15 void merge(int x,int y,int fu,int fv)
16 {
17     f[fu] = fv;
18     link[fu] = (link[x]==link[y] ? 1 : 0);
19 }
20 void init()
21 {
22     for (int i = 0; i <= n; i ++)
23     {
24         f[i] = i;
25         link[i] = 0;
26     }
27 
28 }
29 int main()
30 {
31     int T;
32     scanf("%d",&T);
33     while(T--)
34     {
35 
36         scanf("%d%d%*c",&n,&m);
37         init();
38         while(m--)
39         {
40             int u,v;
41             char s;
42             scanf("%c%d%d%*c",&s,&u,&v);
43             int fu = find(u);
44             int fv = find(v);
45             if (s=='A')
46             {
47                 if(fu!=fv)
48                 {
49                     printf("Not sure yet.\n");
50                     continue;
51                 }
52                 if (link[u]==link[v])
53                 {
54                     printf("In the same gang.\n");
55                     continue;
56                 }
57                 printf("In different gangs.\n");
58                 continue;
59             }
60             if (s=='D')
61             {
62                 if (fu!=fv)
63                     merge(u,v,fu,fv);
64             }
65 
66         }
67     }
68     return 0;
69 }
View Code

 

posted @ 2013-09-06 21:17  N_ll  阅读(200)  评论(0编辑  收藏  举报