1. 程式人生 > >染色 能否構成二分圖 存在多個連通快

染色 能否構成二分圖 存在多個連通快

#include<iostream>
#include<cstring>
#include<cmath>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<functional>

using namespace std;
#define inf 0x3f3f3f3f
#define pi acos(-1.0)
#define LL long long
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
//#define mp make_pair
#define pb push_back
#define ULL unsigned LL
#define mem(a, b) memset(a, b, sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
//#define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout);

const int maxn = 1100;
int mark[maxn];
vector<int> v[maxn];
int n, ans;

void init (){
	mem(mark, 0);
	for (int i = 0; i <= n; ++i) v[i].clear();
	ans = 1;
}

void dfs(int start, int End, int tag){
	if (!ans)//已經知道答案了 快速返回
		return;
	//標記該人關係
	mark[start] = tag;
	for (int i = 0; i < v[start].size(); ++i){
		int ter = v[start][i];
		//不走回頭路
		if (ter == End) continue;
		//如果發現每段 不是對立的關係
		if (mark[ter] == tag){
			ans = 0;
			return;
		}
		
		//注意這裡 不能直接else 不然就會一直迴圈 比如1 3 5 4   1 3 5 4 1  一直重複 沒確定關係才去dfs
		else if (!mark[ter]){
			dfs(ter, start, -tag);
		}
	}
	
}
int main(){
	int m, x, y;
	while (~scanf("%d%d%d%d", &n, &m, &x, &y)){
		init();
		int a, b;
		for (int i = 0; i < m; ++i){
			scanf("%d%d", &a, &b);
			v[a].push_back(b);
			v[b].push_back(a);
		}
		int people;
		//標記好人 壞人
		for (int i = 0; i < x; ++i){
			scanf("%d", &people);
			mark[people] = 1;
		}
		for (int i = 0; i < y; ++i){
			scanf("%d", &people);
			mark[people] = -1;
		}

		//因為圖可能不是連通的  有多個連通快
		//根據已經確定關係的 進而確定對立那個
		for (int i = 1; i <= n; ++i){
			//0是沒確定關係的
			if (mark[i] && v[i].size() >= 1){
				//利用了0 是不存在 這樣dfs  i點就會把i這裡面整個連通塊跑完 確定好裡面的關係
				dfs(i, 0, mark[i]);
			}
		}
		//可能存在  還有一些連通快沒有確定關係
		for (int i = 1; i <= n; ++i){
			if (!mark[i] && v[i].size()){
				dfs(i, 0, 1);//隨便給  假定是好人
			}
		}
		//這樣就把那些連通快(起碼兩個點)都確定了
		//如果仍有沒確定的 那這些就是單個點 作為一個連通快 那他可以好人  可以壞人 輸出NO
		for (int i = 1; i <= n; ++i){
			if (!mark[i]){
				ans = 0;
				break;
			}
		}
		if (ans) printf("YES\n");
		else printf("NO\n");
	}
}