POJ-2492 A Bug's Life(种类并查集)

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

题意:

给出一个T代表几组数据,给出一个n一个m,代表人的编号由1~n,m条命令,每条命令由两个数值组成,代表这两个人性别不同,问所有命令是否符合逻辑

两种写法:

第一种:带权并查集

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 const int INF=0x3f3f3f3f;
14 typedef long long LL;
15 const int mod=1e9+7;
16 const int maxn=1e5+10;
17 using namespace std;
18 
19 int fa[5005];
20 int dis[5005];//表示i和其根结点的关系,1表示异性,0表示同性 
21  
22 void init(int n)
23 {
24     for(int i=0;i<=n;i++)
25         dis[i]=0,fa[i]=i;
26 }
27 int Find(int x)//带权并查集 
28 {
29     if(x!=fa[x])
30     {
31         int t=fa[x];
32         fa[x]=Find(fa[x]);
33         dis[x]=(dis[x]+dis[t])%2;
34     }
35     return fa[x];
36 }
37 
38 int main()
39 {
40     #ifdef DEBUG
41     freopen("sample.txt","r",stdin);
42     #endif
43 //    ios_base::sync_with_stdio(false);
44 //    cin.tie(NULL);
45     
46     int T;
47     scanf("%d",&T);
48     for(int k=1;k<=T;k++)
49     {
50         int n,m;
51         scanf("%d %d",&n,&m);
52         init(n);
53         int flag=0;//flag=1表示找到了错误 
54         for(int i=1;i<=m;i++)
55         {
56             int a,b;
57             scanf("%d %d",&a,&b);
58             if(flag) continue;
59             int aa=Find(a);
60             int bb=Find(b);
61             if(aa==bb)// 二者的祖先相同
62             {
63                 if(dis[a]==dis[b]) flag=1;//且与祖先的性别关系相同,出现错误 
64             }
65             else//二者祖先不同
66             {
67                 fa[bb]=fa[aa];
68                 dis[bb]=(dis[a]+1-dis[b])%2;
69             }
70         }
71         if(k!=1) printf("
");//格式要求 
72         printf("Scenario #%d:
",k);
73         if(flag==1) printf("Suspicious bugs found!
");
74         else printf("No suspicious bugs found!
");
75     }
76     
77     return 0;
78 }

第二种:

fa开两倍空间,fa[i+n]相当于i的对立集合,这种可能耗时会多一点吧

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 const int INF=0x3f3f3f3f;
14 typedef long long LL;
15 const int mod=1e9+7;
16 const int maxn=1e5+10;
17 using namespace std;
18 
19 int fa[5005];
20 void init(int n)
21 {
22     for(int i=0;i<=n;i++)
23         fa[i]=i;
24 }
25 int Find(int x)
26 {
27     return x==fa[x]? x:fa[x]=Find(fa[x]);
28 }
29 void Union(int a,int b)
30 {
31     int aa=Find(a);
32     int bb=Find(b);
33     if(aa!=bb) fa[aa]=bb;
34 }
35 
36 int main()
37 {
38     #ifdef DEBUG
39     freopen("sample.txt","r",stdin);
40     #endif
41 //    ios_base::sync_with_stdio(false);
42 //    cin.tie(NULL);
43     
44     int T;
45     scanf("%d",&T);
46     for(int k=1;k<=T;k++)
47     {
48         int n,m;
49         scanf("%d %d",&n,&m);
50         init(2*n);
51         int flag=0;//flag=1表示找到了错误 
52         for(int i=1;i<=m;i++)
53         {
54             int a,b;
55             scanf("%d %d",&a,&b);
56             if(flag) continue;
57             int aa=Find(a);
58             int bb=Find(b);
59             if(aa==bb) flag=1;// 二者同属一个集合,性别相同 
60             else//二者性别不同,不属于同一个集合 
61             {
62                 Union(a,b+n);//a和b的对立集合同属一个集合 
63                 Union(a+n,b);//b和a的对立集合同属一个集合
64             }
65         }
66         if(k!=1) printf("
");//格式要求 
67         printf("Scenario #%d:
",k);
68         if(flag==1) printf("Suspicious bugs found!
");
69         else printf("No suspicious bugs found!
");
70     }
71     
72     return 0;
73 }

-

原文地址:https://www.cnblogs.com/jiamian/p/12262326.html