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("\n");//格式要求
72 printf("Scenario #%d:\n",k);
73 if(flag==1) printf("Suspicious bugs found!\n");
74 else printf("No suspicious bugs found!\n");
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("\n");//格式要求
67 printf("Scenario #%d:\n",k);
68 if(flag==1) printf("Suspicious bugs found!\n");
69 else printf("No suspicious bugs found!\n");
70 }
71
72 return 0;
73 }
-
来源:https://www.cnblogs.com/jiamian/p/12262326.html