POJ:2492-Bug's Life(二分图的判定)

Bug’s Life

Time Limit: 10000MS
Memory Limit: 65536K

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.


解题心得:

  1. 题意就是一个教授研究一种虫子的配对问题,给你每个虫子的配对情况,问你这些虫子是否存在同性配对。
  2. 其实就是一个二分图的判定,《算法竞赛,训练指南》里面有判定的源代码,这里说两种判定方法
    • 第一种就是先将每个虫子的配对对象用邻接表存起来(存双向边),然后用dfs跑,给开头的那个虫子规定一个性别,然后依次跑下去,如果出现性别冲突,那么说明有同性配对的问题。
    • 第二种就是使用并查集来做,存单向边,还是初始化第一只虫子的性别,然后开始找,找到的合并在一个并查集里面,但是如果找到两个虫子性别相同配对,这时候有两种情况,第一种是两个虫子在一个并查集里面,这样说明有同性配对的问题,第二种就是两个虫子不在一个并查集里面,这时候要将一个并查集的性别全部翻转,然后将两个并查集合并起来继续向下找。
  3. 一个坑点,每个例子之间要输出一个空行,输出就输出嘛,你把这个要求写在输入里面搞毛啊,比赛的时候PE。

dfs判定二分图

#include<stdio.h>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 2010;
vector <int> ve[maxn];
int n,m,sex[maxn],T=1,t;//sex[i]=0代表这个虫子还没有找过,sex[i]=1代表男性,sex[i]=2代表这个虫子是女性

void init()
{
    scanf("%d%d",&n,&m);
    memset(sex,0,sizeof(sex));
    sex[0] = 2;//用于初始化第一个虫子的性别
    for(int i=0;i<=n;i++)
        ve[i].clear();
    while(m--)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        ve[a].push_back(b);
        ve[b].push_back(a);
    }
}

bool dfs(int x,int pre)
{
    sex[x] = 3-sex[pre];
    for(int i=0;i<ve[x].size();i++)
    {
        int v = ve[x][i];
        if(sex[v] == sex[x])
            return false;
        if(!sex[v])
            if(!dfs(v,x))
                return false;
    }
    return true;
}

void checke()
{
    printf("Scenario #%d:
",T++);
    bool flag = true;
    for(int i=1;i<=n;i++)
        if(!sex[i])
        {
            flag = dfs(i,0);
            if(!flag)
            {
                printf("Suspicious bugs found!");
                return ;
            }
        }
    printf("No suspicious bugs found!");
}

int main()
{
    scanf("%d",&t);
    while(t--)
    {
        init();
        checke();
        if(t != 0)
            printf("

");//注意别被坑了
    }
}

乱搞,写的并查集

/*比赛时候的智障代码,写得很乱,将就看吧*/
#include<stdio.h>
#include<iostream>
#include<queue>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
typedef long long ll;
using namespace std;
const int maxn = 2010;
bool maps[maxn][maxn];
struct NODE
{
    int a,b;
}node[maxn*maxn];
int father[maxn];
bool vis[maxn],flag;
int sex[maxn],n,m;

bool cmp(NODE A, NODE B)
{
    return A.a < B.a;
}

void init()
{
    flag = false;//用于标记是否发生同性冲突
    memset(sex,0,sizeof(sex));
    memset(vis,0,sizeof(vis));//用来标记这个虫子是否被找过
    memset(maps,0,sizeof(maps));
    for(int i=1;i<=n;i++)
        father[i] = i;
}

int find(int x)
{
    if(father[x] == x)
        return x;
    return father[x] = find(father[x]);
}

void merge(int a,int b)
{
    int fa = find(a);
    int fb = find(b);
    if(fa != fb)
        father[fa] = fb;
}

int main()
{
    int t = 1;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        init();
        flag = false;
        int cnt = 0;
        for(int i=0;i<m;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            if(a > b)
                swap(a,b);
            if(!maps[a][b])//检查重边,不知道有没有用,反正写了
            {
                maps[a][b] = maps[b][a] = true;
                node[cnt].a = a;
                node[cnt].b = b;
                cnt++;
            }
        }
        sort(node,node+cnt,cmp);
        for(int i=0;i<cnt;i++)
        {
            int a = node[i].a;
            int b = node[i].b;
            if(!vis[a] && !vis[b])
            {
                vis[a] = vis[b] = true;
                merge(a,b);
                sex[a] = 0;
                sex[b] = 1;
            }
            else if(!vis[a] && vis[b])
            {
                sex[a] = !sex[b];
                vis[a] = true;
                merge(a,b);
            }
            else if(!vis[b] && vis[a])
            {
                sex[b] = !sex[a];
                vis[b] = true;
                merge(a,b);
            }
            else if(vis[a] && vis[b])
            {
                if(sex[a] == sex[b])
                {
                    if(find(a) == find(b))//同一并查集中性别冲突
                        flag = true;
                    else
                    {
                        for(int i=1;i<=n;i++)
                            if(find(i) == find(b))//不同并查集中性别冲突,就把其中一个中的性别全部冲突
                                sex[i] = !sex[i];
                        merge(a,b);
                    }
                }
            }
        }
        printf("Scenario #%d:
",t++);
        if(flag)
            printf("Suspicious bugs found!");
        else
            printf("No suspicious bugs found!");
        if(T!=0)
            printf("

");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/GoldenFingers/p/9107195.html