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("\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 }

-

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

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

时间: 2024-11-06 06:53:22

POJ-2492 A Bug's Life(种类并查集)的相关文章

HDU 1829 &amp;&amp; POJ 2492 A Bug&#39;s Life(种类并查集)

题目地址:HDU 1829     POJ 2492 这个题可以用两种方法做,第一眼看完题是觉得用dfs染色判断二分图.然后又写的刚学的种类并查集.原来并查集可以这样用,真是神奇.. dfs染色代码: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #incl

【POJ】2492 A bug&#39;s life ——种类并查集

A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 28211   Accepted: 9177 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders

POJ 2492 A Bug&#39;s Life (并查集)

Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their in

【转】POJ 2492 A Bug&#39;s Life:基础并查集进阶

思路参考这里(较详细) 一开始总是WA调了一晚上原来···Init初始化写在scanf上面了···哎╮(╯▽╰)╭anyway!对并查集的理解更深了一步! #include<cstdio> #include<cstring> using namespace std; #define Size 2000 struct node { int Pre; int Relation;// 与父节点的关系 0同性 1异性 }Bug[Size+1]; int N, M; bool found;

poj 2492 A Bug&#39;s Life 【并查集拓展】

A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 29030   Accepted: 9455 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders

hdu1829A Bug&#39;s Life(种类并查集)

传送门 关键在于到根节点的距离,如果两个点到根节点的距离相等,那么他们性别肯定就一样(因为前面如果没有特殊情况,两个点就是一男一女的).一旦遇到性别一样的,就说明找到了可疑的 1 #include<bits/stdc++.h> 2 using namespace std; 3 int f[2005],n,m,rankk[2005]; 4 bool flag; 5 inline void init() 6 { 7 flag=false; 8 for(int i=0; i<=n; ++i)

hdoj 1829 A bug&#39;s life 种类并查集

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1829 并查集的一个应用,就是检测是否存在矛盾,就是两个不该相交的集合有了交集.本题就是这样,一种虫子有两种性别,每次m次操作,每次给出(a,b),如果a和b是同性别就出现了错误,也就是说出现了判断它有两种性别的错误.我的策略同样是两个集合,用并查集维护两个集合之间的关系.具体证明请看我的上一篇博客,关于这种做法的正确性的证明. 代码如下: 1 #include<bits/stdc++.h> 2 t

POJ - 1703 Find them, Catch them(种类并查集)

题意:N个人,M条关系,A x y表示询问x和y是不是属于同一组,D x y表示x和y是不同组.输出每个询问后的结果. 分析: 1.所有的关系形成一个连通图,如果x和y可达,那两者关系是确定的,否则不能确定. 2.r[tmpy] = r[x] + r[y] + 1;可以更新连通块里祖先的标号. eg: 5 4 D 1 2 D 2 3 D 4 5-----到此为止形成两个连通块,标号如图所示(红笔) D 3 5 第四步,将3和5连边,因为以0为祖先,所以4的标号应当改变,可以发现改变后的r[4]

poj 2492 a bug&#39;s life 简单种类并查集

题意大致为找同性恋的虫子.... 这个比食物链要简单些.思路完全一致,利用取余操作实现关系之间的递推. 个人感觉利用向量,模和投影可能可以实现具有更加复杂关系的并查集. 1 #include<cstdio> 2 using namespace std; 3 const int MAXN=50010; 4 int fa[MAXN]; 5 int rel[MAXN]; // 0代表同类,1代表吃fa[i],2代表被吃 6 void _set(int n) 7 { 8 for(int i=1;i&l

POJ 2492 A Bug&#39;s Life

A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 35756   Accepted: 11730 Description Background Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different gender