HDU5971 Wrestling Match

本文介绍了一种通过染色法解决摔跤比赛中选手分类的问题,即判断所有参赛者能否被正确划分为“好选手”与“坏选手”。利用图论中的二分图原理,通过对已知类别选手进行染色并向其邻居传播颜色来实现分类验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Wrestling Match

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 498    Accepted Submission(s): 226


Problem Description
Nowadays, at least one wrestling match is held every year in our country. There are a lot of people in the game is "good player”, the rest is "bad player”. Now, Xiao Ming is referee of the wrestling match and he has a list of the matches in his hand. At the same time, he knows some people are good players,some are bad players. He believes that every game is a battle between the good and the bad player. Now he wants to know whether all the people can be divided into "good player" and "bad player".
 

Input
Input contains multiple sets of data.For each set of data,there are four numbers in the first line:N (1 ≤ N≤ 1000)、M(1 ≤M ≤ 10000)、X,Y(X+Y≤N ),in order to show the number of players(numbered 1toN ),the number of matches,the number of known "good players" and the number of known "bad players".In the next M lines,Each line has two numbersa, b(a≠b) ,said there is a game between a and b .The next line has X different numbers.Each number is known as a "good player" number.The last line contains Y different numbers.Each number represents a known "bad player" number.Data guarantees there will not be a player number is a good player and also a bad player.
 

Output
If all the people can be divided into "good players" and "bad players”, output "YES", otherwise output "NO".
 

Sample Input
  
5 4 0 0 1 3 1 4 3 5 4 5 5 4 1 0 1 3 1 4 3 5 4 5 2
 

Sample Output
  
NO YES
 

Source

2016ACM/ICPC亚洲区大连站-重现赛(感谢大连海事大学)  

http://acm.split.hdu.edu.cn/showproblem.php?pid=5971

题目意思有点蛋痛 输入N个点 M对关系 后面是已经确定的好人个数  和坏人个数

每对关系里都有一个好人和一个坏人  在下面是已经确定的好人 和 坏人

问是否矛盾 (有点比较蛋痛 就是 a+b==0 OR N=1 的时候就直接NO )

(有的讲是否可以形成二分图) 我的做法是染色法  

跟下面这道题是一样的 不过这道题多了个条件就是把一些点确定了

所以从这些点开始染

http://blog.youkuaiyun.com/xky140610205/article/details/52763988

#include<bits/stdc++.h>
using namespace std;

vector<int>ap[1010];
int vis[1010],viss[1010];
int aa[1010],bb[1010];
int flagg;

int dfs(int u)
{
    int i;
    for(i=0; i<ap[u].size(); i++)
    {
        int v=ap[u][i];
        if(vis[v]==vis[u])
        {
            flagg=1;
            return 1;
        }
        if(!vis[v])
        {
            viss[v]=1;
            vis[v]=-vis[u];
            dfs(v);
        }
        if(flagg)
            return 1;
    }
    return 0;
}

int main()
{
    int n,m,a,b,i,c,d,flag;
    while(scanf("%d%d%d%d",&n,&m,&a,&b)!=EOF)
    {
        if(n==1)
        {
            printf("NO\n");
            continue;
        }
        memset(vis,0,sizeof(vis));
        memset(viss,0,sizeof(viss));
        for(i=0; i<1010; i++)
            ap[i].clear();
        while(m--)
        {
            scanf("%d%d",&c,&d);
            ap[c].push_back(d);
            ap[d].push_back(c);
        }
        for(i=0; i<a; i++)
        {
            scanf("%d",&c);
            aa[i]=c;
            vis[c]=1;
        }
        for(i=0; i<b; i++)
        {
            scanf("%d",&d);
            bb[i]=d;
            vis[d]=-1;
        }
        if(a+b==0)
        {
            printf("NO\n");
            continue;
        }

        flag=0;
        flagg=0;
        for(i=0; i<a; i++)
        {
            if(!viss[aa[i]])
            {
                flag=dfs(aa[i]);
                viss[aa[i]]=1;
            }
            if(flag)
                break;
        }

        if(!flag)
            for(i=0; i<b; i++)
            {
                if(!viss[bb[i]])
                {
                    flag=dfs(bb[i]);
                    viss[bb[i]]=1;
                }
                if(flag)
                    break;
            }

        for(i=1; i<=n; i++)
        {
            if(!viss[i])
            {
                viss[i]=1;
                vis[i]=1;
                flag=dfs(i);
            }
            if(flag)
                break;
        }
        if(flag)
            printf("NO\n");
        else printf("YES\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值