POJ-2492 A Bug's Life(二分图染色 或者 种类并查集)

佐手、 提交于 2019-12-10 20:27:48

A Bug’s Life

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.

题意:有t组测试数据, 对于每组数据,第一行n, m分别表示昆虫的数目和接下来m行x, y, x, y表示教授判断x, y为异性, 问教授是否有错误判断,即存在x, y为同性;

思路:这题可以用二分图的染色法来做,只需要判断给的x,y的颜色是否一样就行了。
还可以用种类并查集,设d[x]这个数组,(d[x]这个数组可以理解为x到它祖先节点的距离)。因为这题只有两个性别,就是两种状态,所以可以让d[x]%2。如果d[x]=0就代表x和他的父亲节点是同性的,反之就是异性。

为什么要取余2,可以看下图
在这里插入图片描述
如果当前节点与其祖先节点的距离为奇数的话,他们肯定是异性的,如果为偶数就是同性,所以只有奇偶两种状态,就可以对d[x]%2。

用二分图染色法的代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

#define maxn 1000010
#define ll long long
#define inf 0x3f3f3f3f

int n,m,Case=1;
vector<int>v[maxn];
int color[maxn];

int bfs(int u)
{
    queue<int> q;
    q.push(u);
    if(color[u]==0)
    color[u]=1;
    while(!q.empty())
    {
        int k=q.front();
        q.pop();
        for(int i=0;i<v[k].size();i++)
        {
            int j=v[k][i];
            if(color[j]==color[k])
                return 0;
            else if(color[j]==0)
            {
                color[j]=-color[k];
                q.push(j);
            }
        }
    }
    return 1;
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        memset(color,0,sizeof(color));
        scanf("%d %d",&n,&m);
        for(int i=0;i<=n;i++)
            v[i].clear();
        int x,y,u=0;
        while(m--)
        {
            scanf("%d %d",&x,&y);
            if(u==0) u=x;
            v[x].push_back(y);
            v[y].push_back(x);
        }
        int flag=0;
        for(int i=1;i<=n;i++)
            if(!bfs(i)) flag=1;
        printf("Scenario #%d:\n",Case++);
        if(!flag) printf("No suspicious bugs found!\n");
        else printf("Suspicious bugs found!\n");
        printf("\n");
    }
    return 0;
}

种类并查集代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
using namespace std;

#define ll long long
const int inf=0x3f3f3f3f;
const int maxn=20010;
#define eps 1e-8

int t,n,m,cas=1;
int pre[maxn],d[maxn];

int Find(int x)
{
    if(x==pre[x]) return x;
    int tmp=Find(pre[x]);
    d[x]=(d[x]+d[pre[x]])%2;
    pre[x]=tmp;
    return tmp;
}

void join(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    if(fx!=fy)
    {
        pre[fx]=fy;
        d[fx]=(d[y]-d[x]+1+2)%2;
    }
}

void init()
{
    for(int i=0;i<=n;i++)
    {
        pre[i]=i;
        d[i]=0;
    }
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&n,&m);
        init();
        int x,y,flag=0;
        while(m--)
        {
            scanf("%d %d",&x,&y);
            if(flag) continue;
            int fx=Find(x);
            int fy=Find(y);
            if(fx==fy)
            {
                if(d[x]==d[y]) flag=1;
            }
            else join(x,y);
        }
         if(flag) printf("Scenario #%d:\nSuspicious bugs found!\n\n", cas++);
        else printf("Scenario #%d:\nNo suspicious bugs found!\n\n", cas++);
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!