题目链接Wrestling Match - HDU 5971 - Virtual Judge
Wrestling Match
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 6322 Accepted Submission(s): 2201
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
Recommend
wange2014
题目大意
目前有N个点,M条线。N个点状态可以为好,孬和不确定。M条线,每条线连接的两个点一定是一好一孬的。此外还预先知道了几个点的好孬装填,问你能否凭这些信息确定所有点的好孬状态。
分析
近乎赤裸的二分图染色问题。唯一的坑在于合法性的判断。对于有线连接的点,可以在“每条线连接的两个点一定是一好一孬的”的前提下随意染色。而没有线连接的点只能预知颜色,不能后天染色。
开始前定义个枚举*enum* Stat{BLACK=-1, UNKNOWN=0, WHITE=1}
表示每个点的颜色可取值:黑色,未染色,白色。
首先建图,这一过程中对题目输入中所有提到的点都打个mention标记,表示这些点要么已经有颜色,要么可以被后天染色。
然后对每个颜色已知且未被访问过的点做dfs,把与它能连通且颜色未定的点全染上色。
再然后对每个颜色未知且为访问过的点染成黑色,然后做dfs,把与它能连通且颜色未定的点全染上色。
最后合法性检验,看看是不是知道了所有点的颜色,并且每条线连着的点颜色都不冲突。
AC代码
#include <bits/stdc++.h>
using namespace std;
#define DEBUG 0
#define plog if(DEBUG) std::cout
const int MAXN=1000+5;
enum Stat{BLACK=-1, UNKNOWN=0, WHITE=1}; // 染色状态可取值的集合:黑色,未染色,白色
vector<int> G[MAXN];
int st[MAXN]; // 每个点染色状态
bool vis[MAXN]; // 访问标记
bool legal; // 合法性标记
bool ment[MAXN]; // 在输入阶段是否提及
void init(int n){
for(int i=0;i<=n;i++){
G[i].clear();
st[i]=UNKNOWN;
vis[i]=false;
ment[i]=false;
}
legal=true;
}
void dfs(int u){
vis[u]=true;
for(int v:G[u]){
if(!vis[v]){
if(st[v]==UNKNOWN){
st[v]=-st[u];
}
dfs(v);
}
}
}
int main(){
ios::sync_with_stdio(0);
int n,m,cntx,cnty;
while(cin>>n>>m>>cntx>>cnty){
init(n);
for(int i=0;i<m;i++){
int u,v;
cin>>u>>v;
G[u].push_back(v);
G[v].push_back(u);
ment[u]=ment[v]=true;
}
for(int i=0;i<cntx;i++){
int x;
cin>>x;
ment[x]=true;
st[x]=WHITE;
}
for(int i=0;i<cnty;i++){
int x;
cin>>x;
ment[x]=true;
st[x]=BLACK;
}
for(int i=1;i<=n;i++){
if(st[i]!=UNKNOWN && !vis[i]){
plog<<__LINE__<<" "<<i<<"\n";
dfs(i);
}
}
for(int i=1;i<=n;i++){
if(!vis[i] && ment[i]){
plog<<__LINE__<<" "<<i<<"\n";
st[i]=BLACK;
dfs(i);
}
}
if(DEBUG){
for(int i=1;i<=n;i++) cout<<st[i]<<" ";
}
for(int i=1;i<=n;i++){
if(st[i]==UNKNOWN){
legal=false;
}
}
for(int u=1;u<=n && legal;u++){
for(int v:G[u]){
if(st[u]!=-st[v]){
legal=false;
break;
}
}
}
if(legal) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}