您的位置:首页 > 其它

HDU 5971 Wrestling Match 2016大连区域赛

2016-11-06 18:50 239 查看
Wrestling Match
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 8    Accepted Submission(s): 7

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亚洲区大连站-重现赛(感谢大连海事大学)


题意比较不明…看了很久才搞出来 个人理解 就是:

n个人 给定m对关系:a,b不在一个集合中

已知x个人是好球员的集合中的人

y个人是坏球员

判断是否能分成2个集合

如果1是好球员 2是坏球员

其余的球员与1,2无关系 能分成2个集合 也算YES

并查集

x的球员设置在集合1 y的在集合0

先以x和y的球员作为起点 dfs确定球员关系

如果dfs中发现关系矛盾 ->NO

dfs完了 如果还有球员没确定集合 随便给一个没集合的球员设个集合

以该球员作为起点dfs

如果dfs完了 还有球员不能确定集合 ->NO

否则YES

坑爹的是!!!!!居然爆栈………

于是dfs改成队列…..就过了

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
#include<stack>
#include<time.h>
#include<math.h>
#include<list>
#include<cstring>
#include<fstream>
//#include<memory.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define INF 1000000007
#define pll pair<ll,ll>
#define pid pair<int,double>

const int N=1000+5;
const int M=10000+5;

int par
;
inline int find(int x){
return x==par[x]?x:par[x]=find(x);
}
vector<int>against
;//against[i]保存与i不在一个集合的
vector<int>known;//保存x y的球员
bool visited
;
bool dfs(int u){
deque<int>de;
de.push_back(u);
while(!de.empty()){
u=de[0];
de.pop_front();
if(visited[u])
continue;
visited[u]=true;
for(int i=0;i<against[u].size();++i){
int v=against[u][i];
if(par[v]<0){
par[v]=1^par[u];
de.push_back(v);
}
else
if(par[v]+par[u]!=1)//矛盾
return false;
}
}
return true;
}

bool slove(int n){
for(int i=0;i<known.size();++i){//以x y中的球员作起点 找一遍
int u=known[i];
if(visited[i]==true)
continue;
if(dfs(i)==false)
return false;
}
for(int i=1;i<=n;++i){//有球员没有与任何球员有对立关系 又不是已知good bad 必定NO
if(against[i].size()==0&&par[i]<0)
return false;
}
int t=-1;//标记第一个没集合的球员
for(int i=1;i<=n;++i){
if(par[i]<0){
t=i;
par[t]=0;//设置成集合0
break;
}
}
if(t<0)//所有球员都有集合了
return true;
if(dfs(t)==false)
return false;
for(int i=1;i<=n;++i)//还有球员没集合
if(par[i]<0)
return false;
return true;
}

int main()
{
//freopen("/home/lu/文档/r.txt","r",stdin);
//freopen("/home/lu/文档/w.txt","w",stdout);
int n,m,x,y;
while(~scanf("%d%d%d%d",&n,&m,&x,&y)){
for(int i=1;i<=n;++i){
par[i]=-1;
visited[i]=false;
against[i].clear();
}
known.clear();
for(int i=0,u,v;i<m;++i){
scanf("%d%d",&u,&v);
against[u].push_back(v);
against[v].push_back(u);
}
for(int i=0,u;i<x;++i){
scanf("%d",&u);
par[u]=1;//good=1
known.push_back(u);
}
for(int i=0,u;i<y;++i){
scanf("%d",&u);
par[u]=0;//bad=0
known.push_back(u);
}
puts(slove(n)?"YES":<
13089
span class="hljs-string">"NO");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息