「一本通 3.5 练习 5」和平委员会
题面
哇真的是板子
如果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\n"); return 0;
}
for(int i = 1; i <= n; ++i){
if(col[i << 1] < col[(i << 1) - 1]) printf("%d\n", (i << 1));
else printf("%d\n", (i << 1) - 1);
}
return 0;
}