Wrestling Match
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 323 Accepted Submission(s): 146
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
NO YES
题意:
大概意思是有n个编号为1~n的人,每个人应该都有一个“好”或“坏”的属性,并且题上已知有m对“好坏”的组队,在这m对里每一对有2个人,并且这2个人一定有一个是“好”人,另外一个是“坏”人,但是并不知道他们到底谁是”好”或”坏”。而且会告诉你有x个编号已知的“好”人,也有y个编号已知的“坏”人。现在告诉你这些条件,让你判断这n个人是否能全部分清“好”或“坏”的属性。
在样例1中:1和4,1和3,3和5,4和5,0个已知好人和0个已知坏人,所以我们可以假设1是好人,则3,4是坏人,推理5号是好人,没有冲突,所以,1,3,4,5,是可以确定的。2号无论为坏人或好人都可以,所以2号未知。则2号无法满足题目要求,所以是NO
而在样例2中,多了一个已知2号是好人的条件,所以1~5号都已知,满足题目要求,所以是YES。
这道题的解题思路就是用链式前向星储存m组相连的人,再在已知的好人和坏人中判断与之有联系的人的属性,如果有冲突,比如1和3,1和2,2和3,其中2和3就有冲突,这种情况用一个标记好坏属性的数组来处理,如果已知1是好人,标记a[1]=1,则与之相连的2和3就是坏人,则标记a[2]=a[3]=0,再继续找2和3相连的,如果发现相连的有冲突,则确定有冲突,直接返回NO。如果遍历完相连的每个点。发现都符合,则表示这几组都正常。
当判断完题目已知的好人和坏人时,再遍历一下看谁的属性还未确定,如果发现这个人是个独点,直接判断NO。如果不是独点的话,重复上面的判断过程,在判断的时候可以随意给起始的搜索点一个状态,然后搜索判断。其中判断的过程我是用DFS写的。
PS:一定,一定,一定要注意清空。(我因为没有清空数组,结果一直WA)/(ㄒoㄒ)/~~。。。。但是!!但是!!神奇的是即使不清空vector,我在搜索的时候加了个判断搜索点是否大于N,如果大于则直接返回。结果神奇的AC了。真有毒~~~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <map>
#include <set>
#include <queue>
#include <vector>
#define inf 0x6fffffff
#define LL long long
#define mem(p,k) memset(p,k,sizeof(p));
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int f[2010],g[2010],h[2010][2010],num[2010],n;
vector<int>a[1010];
int dfs(int x){
for(int i=0;i<a[x].size();i++){
// if(a[x][i]>n){
// continue;
// }
//cout<<x<<"="<<a[x][i]<<endl;
if(g[a[x][i]]==-1){
g[a[x][i]]=g[x]^1;
//cout<<a[x][i]<<"="<<g[a[x][i]]<<en
}
else {
if(g[x]==g[a[x][i]])return 0;
}
if(!h[x][a[x][i]]){
h[x][a[x][i]]=1;
h[a[x][i]][x]=1;
if(dfs(a[x][i])==0){
return 0;
}
}
}
return 1;
}
int main()
{
int m,x,y,k,cur;
while(~scanf("%d%d%d%d",&n,&m,&x,&y)){
for(int i=0;i<1010;i++){
a[i].clear();
}
for(int i=1;i<=n;i++)f[i]=i;
for(int i=0;i<m;i++){
int x1,x2;
scanf("%d%d",&x1,&x2);
a[x1].push_back(x2);
a[x2].push_back(x1);
}
mem(g,-1);
mem(h,0);
mem(num,0);
k=0;
cur=1;
for(int i=0;i<x;i++){
scanf("%d",num+k);
g[num[k]]=1;
k++;
}
for(int i=0;i<y;i++){
scanf("%d",num+k);
if(g[num[k]]!=-1){
cur=0;
}
g[num[k]]=0;
k++;
}
if(!cur){
cout<<"NO"<<endl;continue;
}
cur=1;
for(int i=0;i<k;i++){
if(dfs(num[i])==0){
cout<<"NO"<<endl;
cur=0;
break;
}
}
if(!cur)continue;
cur=1;
for(int i=1;i<=n;i++){
if(g[i]==-1){
// cout<<i<<endl;
g[i]=1;
if(a[i].empty()||!dfs(i)){
cout<<"NO"<<endl;
// for(int i=1;i<=n;i++){
// cout<<i<<"="<<g[i]<<endl;
// }
cur=0;break;
}
}
}
if(cur)cout<<"YES"<<endl;
}
return 0;
}