二分图的判断

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ACMER_2333/article/details/78483891

hdu-5971 二分图的判断

题意:给出若干组参赛者的信息,每组中都有一个goog player和bad player,再给出确定为good player和bad player的序号,问这些参赛者是否可以分成good player和bad player两大类。

先从good player 和 bad player 开始深搜,搜完后从剩余人中深搜,在搜索过程中,如果遇到矛盾的情况直接输出NO,否则的话输出YES

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAX_V = 1010;
int V,E;
int col[1010];///用来记录每位参赛者的信息(0:好坏信息未知,1:good player ,-1:bad player)
vector<int> G[MAX_V];///邻接表来存参赛者之间的关系
int n,m,x,y;
int vis[1010];//记录每位参赛者在样例中的是否出现(0:未出现,1:出现)
bool dfs(int s,int c)
{
     col[s]=c;
     for(int i=0;i<G[s].size();i++)
     {
         if(col[G[s][i]]==col[s])
            return false;
        if(col[G[s][i]]==0&&!dfs(G[s][i],-c))//再次搜索时,要改变c的值,因为一对参赛者的好坏属性是不一样的
            return false;
     }
     return true;
 }
int main()
{
    while(~scanf("%d%d%d%d",&n,&m,&x,&y))
    {
        memset(col,0,sizeof(col));
        memset(vis,0,sizeof(vis));
        int a,b,sum=0;///sum是用来记录样例中出现的参加比赛的人数
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
            if(!vis[a])
            {
                vis[a]=1;
                sum++;
            }
            if(!vis[b])
            {
                vis[b]=1;
                sum++;
            }
        }
        int dis;
        for(int i=1;i<=x;i++)
        {
            scanf("%d",&dis);
            col[dis]=1;
            if(!vis[dis])
            {
                vis[dis]=1;
                sum++;
            }
        }
        for(int i=1;i<=y;i++)
        {
            scanf("%d",&dis);
            col[dis]=-1;
            if(!vis[dis])
            {
                vis[dis]=1;
                sum++;
            }
        }
        if(sum!=n)  /////sum!=n,导致某些参赛者的信息无法判断(究竟是好人还是坏人无法判断),直接输出NO
        {
            printf("NO\n");
            continue;
        }
        int flog=0;
        ///////先从good player 开始深搜///////
        for(int i=1;i<=n;i++)
        {
            if(col[i]==1)
            {
                if(!dfs(i,1))
                {
                   flog=1;
                   break;
                }
            }
        }
        ////从bad player 开始深搜////
        for(int i=1;i<=n;i++)
        {
            if(col[i]==-1)
            {
                if(!dfs(i,-1))
                {
                   flog=1;
                   break;
                }
            }
        }
        ////从还未确定信息的参赛者深搜///
        for(int i=1;i<=n;i++)
        {
            if(col[i]==0)
            {
                if(!dfs(i,1))
                {
                   flog=1;
                   break;
                }
            }
        }
//        for(int i=1;i<=n;i++)
//            cout<<col[i]<<endl;
        if(flog)
            printf("NO\n");
        else
            printf("YES\n");
        for(int i=1;i<=n;i++)
            G[i].clear();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ACMER_2333/article/details/78483891