您的位置:首页 > Web前端

poj_2492 A Bug's Life(并查集)

2017-01-18 14:51 274 查看
A Bug's Life

Time Limit: 10000MS Memory Limit: 65536K
Total Submissions: 35390 Accepted: 11606
Description
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 interactions were easy
to identify, because numbers were printed on their backs.
Problem

Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.
Input
The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space.
In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.
Output
The output for every scenario is a line containing "Scenario #i:", where i is the number of the scenario starting at 1, followed by one line saying either "No suspicious bugs found!" if the experiment is consistent with his assumption
about the bugs' sexual behavior, or "Suspicious bugs found!" if Professor Hopper's assumption is definitely wrong.
Sample Input
2
3 3
1 2
2 3
1 3
4 2
1 2
3 4

Sample Output
Scenario #1:
Suspicious bugs found!

Scenario #2:
No suspicious bugs found!

Hint
Huge input,scanf is recommended.

给出若干种配对,求是否可能有同性恋。
--------------------
一种做法是扩展数组,让i+n表示非男或非女。
男女配对x---y,就可以表示为 x与(y+n)、y与(x+n) 为同种性别,构建并查集。
这样当给出配对x----y,查询到x与y的父节点相同时,即他们性别相同,说明他们是同性恋。
--------------------
另一种做法,直接用题目给出的配对构建并查集,
同时用数组link[i]表示i与父节点是同性还是异性,分别用0和1表示,一开始父节点都是自己,所以都为0。
给出配对后,跟配对中双方的父节点情况来判断link[i]的取值,
同时在路径压缩时,推出目前节点与父节点的性别关系,自己演算一下,规律出来了。
不过要注意路径压缩时最好用递归的方法,这样关系比较好推,如果用迭代的方法要保证能把所有有关的关系都用上。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <bitset>
#include <queue>
#include <set>

//扩展数组方法
#include <map>
#include <string>
#include <algorithm>
#define FOP freopen("data.txt","r",stdin)
#define FOP2 freopen("data1.txt","w",stdout)
#define inf 0x3f3f3f3f
#define maxn 4010
#define mod 1000000007
#define PI acos(-1.0)
#define LL long long
using namespace std;

int n, m;
int pre[maxn];

int findUF(int x)
{
int r = pre[x];
while(pre[r] != r) r = pre[r];

int i = x, j;
while(i != r)
{
j = pre[i];
pre[i] = r;
i = j;
}

return r;
}

void joinUF(int x, int y)
{
int fx = findUF(x), fy = findUF(y);
if(fx != fy) pre[fx] = fy;
}

int main()
{
int casen = 0;
int T;
scanf("%d", &T);
while(T--)
{
bool flag = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= 2*n; i++) pre[i] = i;
int x, y;
for(int i = 0; i < m; i++)
{
scanf("%d%d", &x, &y);
joinUF(x, y+n);
joinUF(y, x+n);
if(findUF(x) == findUF(y)) flag = 1;
}

printf("Scenario #%d:\n", ++casen);
if(flag) printf("Suspicious bugs found!\n");
else printf("No suspicious bugs found!\n");

if(T != 0) printf("\n");
}
return 0;
}


//常规方法
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <bitset>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#define FOP freopen("data.txt","r",stdin)
#define FOP2 freopen("data1.txt","w",stdout)
#define inf 0x3f3f3f3f
#define maxn 4010
#define mod 1000000007
#define PI acos(-1.0)
#define LL long long
using namespace std;

int n, m;
int pre[maxn];
int link[maxn]; //link[i]为0表示i与父节点是同性,1表示i与父节点是异性

/*
int findUF(int x)
{
int r = pre[x];
while(pre[r] != r) r = pre[r];

int temp;
while(x != r)
{
temp = pre[x];
pre[x] = r;
link[x] = (link[x]+link[temp])%2; // 一开始天真了,这里的每一个x只用上了两组关系
x = temp;
}

return r;
}
*/

int findUF(int x)
{
int temp = pre[x];
if(temp == x) return x;

pre[x] = findUF(temp);
link[x] = (link[x] + link[temp]) % 2;

return pre[x];
}

void joinUF(int x, int y)
{
int fx = findUF(x), fy = findUF(y);
if(fx != fy) pre[fx] = fy, link[fx] = (link[x]+link[y]+1)%2;
}

int main()
{
int casen = 0;
int T;
scanf("%d", &T);
while(T--)
{
bool flag = 0;
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) pre[i] = i, link[i] = 0;
int x, y;
for(int i = 0; i < m; i++)
{
scanf("%d%d", &x, &y);
if(findUF(x) == findUF(y))
{
if(link[x] == link[y]) flag = 1;
}
else joinUF(x, y);
}

printf("Scenario #%d:\n", ++casen);
if(flag) printf("Suspicious bugs found!\n");
else printf("No suspicious bugs found!\n");

if(T != 0) printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: