NP-Hard Problem (cf-687A 二分图判断)

#pragma warning (disable : 4996)
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int maxn = 2e5 + 10;
struct node {
	int to, nxt;
}edge[maxn];

int head[maxn], col[maxn];

int ecnt = 0;
void addedge(int u, int v) {//邻接表比vector快
	edge[ecnt].to = v;
	edge[ecnt].nxt = head[u];
	head[u] = ecnt++;
}

bool bfs(int s) {//染色 判断二分图
	queue<int> q;
	col[s] = 1;
	q.push(s);
	while (!q.empty()) {
		s = q.front();
		q.pop();
		for (int i = head[s]; i + 1; i = edge[i].nxt) {
			if (col[edge[i].to] == 0)
				col[edge[i].to] = -col[s], q.push(edge[i].to);
			if (col[edge[i].to] == col[s])
				return false;
		}
	}
	return true;
}
vector<int> ans1, ans2;

int main()
{
	int n, m;
	scanf("%d%d", &n, &m);
	ans1.clear(); ans2.clear();
	ecnt = 0;
	memset(head, -1, sizeof head);
	for (int i = 0; i < m; ++i) {
		int a, b;
		scanf("%d%d", &a, &b);
		addedge(a, b);
		addedge(b, a);//必须加双边,为什么?
	}
	memset(col, 0, sizeof(col));
	bool flag = true;
	for (int i = 1; i <= n; ++i) {//要历遍所有有边的点全部染色
		if (head[i] == -1)	continue;
		if (col[i] == 0)	flag = bfs(i);
		if (!flag)	break;
	}
	if (!flag) {
		puts("-1");
	}
	else {
		for (int i = 1; i <= n; ++i) {
			if (col[i] == -1) {
				ans1.push_back(i);
			}
			else if (col[i] == 1) {
				ans2.push_back(i);
			}
		}
		int len = ans1.size();
		printf("%d\n", len);
		for (int i = 0; i < len; ++i) {
			if (i) printf(" ");
			printf("%d", ans1[i]);
		}
		len = ans2.size();
		printf("\n%d\n", len);
		for (int i = 0; i < len; ++i) {
			if (i) printf(" ");
			printf("%d", ans2[i]);
		}
		puts("");
	}
	return 0;
}

posted @ 2020-08-04 20:07  wansheking  阅读(169)  评论(0)    收藏  举报