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

题面

loj

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

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#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;   
}

转载于:https://www.cnblogs.com/hjmmm/p/10672758.html

你可能感兴趣的:(「一本通 3.5 练习 5」和平委员会)