题目大意:
给出 n 个人,m 场 比赛 x 个已经确定的好人 y 个已经确定的坏人。
每场比赛由 好人和坏人 组成。
问是否能够将每个人划分成好人或者坏人。
DFS染色看起来很好解决。
1.先开一个flag数组用来标记,对于已经分毫伙的一些人,flag直接标记为1.
2.剩下的开始染色,先从知道确定关系的人染色,染色过程中如果出现矛盾,直接跳出dfs函数,返回false即可。
3.对于关系未确定的,枚举即可。
最后遍历一下flag数组,舅能确定有没有分好伙了。
代码:
//
// main.cpp
// 160929
//
// Created by 刘哲 on 17/5/30.
// Copyright © 2016年 my_code. All rights reserved.
//#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <string.h>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <list>
#include <bitset>
#include <stack>
#include <stdlib.h>
#define lowbit(x) (x&-x)
typedef long long ll;
using namespace std;
const int N = 1010;
int color[N], graph[N][N];
//0为白色,1为黑色
bool bfs(int s, int n) {
queue<int> q;
q.push(s);
color[s] = 1;
while(!q.empty()) {
int from = q.front();
q.pop();
for(int i = 1; i <= n; i++) {
if(graph[from][i] && color[i] == -1) {
q.push(i);
color[i] = !color[from];//染成不同的颜色
}
if(graph[from][i] && color[from] == color[i])//颜色有相同,则不是二分图
return false;
}
}
return true;
}
int main()
{
int n, m, a, b, i,x,y;
int ff[1010];
while(cin >> n >> m>>x>>y)
{
memset(ff,0,sizeof(ff));
memset(color, -1, sizeof(color));
for(i = 0; i < m; i++)
{
cin >> a >> b;
graph[a][b] = graph[b][a] = 1;
ff[a] = ff[b] = 1;
}
int tmp;
while(x--)
{
cin>>tmp;
ff[tmp] = 1;
}
while(y--)
{
cin>>tmp;
ff[tmp] = 1;
}
bool flag1 = true;
for(int i=1;i<=n;i++)
{
if(!ff[i])
{
flag1 = false;
break;
}
}
bool flag = false;
for(i = 1; i <= n; i++)
if(color[i] == -1 && !bfs(i, n))
{//遍历各个连通分支
flag = true;
break;
}
if(flag)
cout << "NO" <<endl;
else
if(flag1)
cout << "YES" <<endl;
else
cout<<"NO"<<endl;
}
return 0;
}