HDU5971 Wrestling Match(二分图染色)

来源:互联网 发布:sql给表添加元素 编辑:程序博客网 时间:2024/05/10 07:15

题意: 给出比赛的人的标号, 以及x个好人y个坏人。询问是否能判断他是一个好人或者坏人。 给出的关系是否不存在矛盾,并且没有既是好人又是坏人。

思路:

训练的时候这题理解错了,一直没过。 补题发现可以是多个连通块,就是说可以分为m堆,只要每个堆里不存在矛盾关系,且每个人都出现过就可以。


#include <cstdio>#include <vector>#include <cstring>using namespace std;const int maxn=10005;int go[maxn];int vis[maxn];int col[maxn];int bad[maxn];vector<int >vec[maxn];int dfs(int u){    go[u]=1;    for(int i=0;i<vec[u].size();i++)    {        int v=vec[u][i];        if(!col[v] &&!bad[v] )        {            col[v]=!col[u];            if(!dfs(v))            return 0;        }        else        {            if(col[v]==col[u])  return 0;        }    }    return 1;}int main(){    int n,m,x,y;    while(~scanf("%d%d%d%d",&n,&m,&x,&y))    {        for(int i=0;i<=n;i++)            vec[i].clear();        memset(bad,0,sizeof(bad));        memset(col,0,sizeof(col));        memset(go,0,sizeof(go));        memset(vis,0,sizeof(vis));        for(int i=1;i<=m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            vec[u].push_back(v);            vec[v].push_back(u);            vis[u]=vis[v]=1;        }        for(int i=1;i<=x;i++)        {            int u;            scanf("%d",&u);            vis[u]=col[u]=1;        }        for(int i=1;i<=y;i++)        {            int u;            scanf("%d",&u);            vis[u]=1;            bad[u]=1;            col[u]=0;        }        int cnt=0;        for(int i=1;i<=n;i++)        {            if(vis[i]) cnt++;        }        if(cnt<n){printf("NO\n");}        else        {            int yes=1;            for(int i=1;yes&&i<=n;i++)            {                if(go[i]) continue;                if(!dfs(i))                {                    yes=0;                }            }            if(yes) printf("YES\n");            else printf("NO\n");        }    }    return 0;}


0 0