「一本通 3.5 练习 5」和平委员会

题面

loj

哇真的是板子
如果a1, b1有矛盾
那么选a1就必须选b0,反之亦然

#include <cmath>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <complex>
#include <ctime>
#include <vector>
#define mp(x, y) make_pair(x, y)
#define par(x) ((x - 1) ^ 1) + 1
using namespace std;
const int N = 2e4 + 5;
struct Edge{
	int v, next;
}edge[N];
int head[N], esize;
inline void addedge(int x, int y){
	edge[++esize] = (Edge){y, head[x]}; head[x] = esize;
}

int n, m;
int dfn[N], low[N], tim;
int col[N], colsize, stk[N], top;
bool vis[N];
void tarjan(int x){
	stk[++top] = x; vis[x] = 1;
	dfn[x] = low[x] = ++tim;
	for(int i = head[x], vv; ~i; i = edge[i].next){
		vv = edge[i].v;
		if(!dfn[vv]) tarjan(vv), low[x] = min(low[x], low[vv]);
		else if(vis[vv]) low[x] = min(low[x], dfn[vv]);
	}
	if(low[x] == dfn[x]){
		++colsize;
		do{
			col[stk[top]] = colsize; vis[stk[top]] = 0;
		}while(top && stk[top--] != x);
	} 
}

int main(){
	memset(head, -1, sizeof(head));
	scanf("%d%d", &n, &m);
	for(int i = 1, x, y; i <= m; ++i){
		scanf("%d%d", &x, &y);
		addedge(x, par(y)); addedge(y, par(x));
	}
	for(int i = 1; i <= (n << 1); ++i)
		if(!dfn[i]) tarjan(i);
	for(int i = 1; i <= n; ++i)
		if(col[i << 1] == col[(i << 1) - 1]){
			printf("NIE
"); return 0;
		}
	for(int i = 1; i <= n; ++i){
		if(col[i << 1] < col[(i << 1) - 1]) printf("%d
", (i << 1));
		else printf("%d
", (i << 1) - 1);
	}
    return 0;	
}
原文地址:https://www.cnblogs.com/hjmmm/p/10672758.html