码迷,mamicode.com
首页 > 其他好文 > 详细

[POI2001]和平委员会

时间:2020-05-09 23:20:49      阅读:85      评论:0      收藏:0      [点我收藏+]

标签:lin   top   mes   委员会   blog   exit   总结   https   min   

2-SAT裸题

如果不会2-SAT,点

总结一下2-SAT其实就是若a则非b这样的形式,建一条边即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 16010;
const int M = 40010;
struct node{
    int pre, to;
    node() {
        pre = to = 0;
    }
    node(int _pre, int _to) {
        pre = _pre;
        to = _to;
    }
}edge[M];
int head[N], tot;
int n, m;
int dfn[N], low[N], stk[N], top, dep, c, col[N];
bool vis[N];
void tarjan(int x) {
    dfn[x] = low[x] = ++dep;
    stk[++top] = x;
    vis[x] = 1;
    for (int i = head[x]; i; i = edge[i].pre) {
        int y = edge[i].to;
        if (!dfn[y]) {
            tarjan(y);
            low[x] = min(low[x], low[y]);
        } else if (vis[y]) {
            low[x] = min(low[x], dfn[y]);
        }
    }
    if (low[x] == dfn[x]) {
        c++;
        col[x] = c;
        vis[x] = 0;
        while (stk[top] != x) {
            col[stk[top]] = c;
            vis[stk[top]] = 0;
            top--;
        }
        top--;
    }
}
inline void add(int u, int v) {
    edge[++tot] = node(head[u], v);
    head[u] = tot;
}
inline int read() {
    int ret = 0, f = 1;
    char ch = getchar();
    while (!isdigit(ch)) {
        if (ch == -) f = -1;
        ch = getchar();
    }
    while (isdigit(ch)) {
        ret = (ret << 1) + (ret << 3) + ch - 0;
        ch = getchar();
    }
    return ret * f;
}
inline int FP(int x) {
    if (x % 2) return x + 1;
    return x - 1;
}
void write(int x) {
    if (x > 9) write(x / 10);
    putchar(x % 10 + 0);
}
inline void print(int x) {
    if (x < 0) {
        putchar(-);
        x = -x;
    }
    write(x);
    putchar(\n);
}
int main() {
    n = read(); m = read();
    for (int i = 1, a, b; i <= m; ++i) {
        a = read();
        b = read();
        add(a, FP(b));
        add(b, FP(a));
    }
    for (int i = 1; i <= n << 1; i++) {
        if (!dfn[i]) {
            tarjan(i);
        }
    }
    for (int i = 1; i <= n << 1; i += 2) {
        if (col[i] == col[i + 1]) {
            puts("NIE");
            exit(0);
        }
    }
    for (int i = 1; i <= n << 1; i += 2) {
        if (col[i] < col[i + 1]) {
            print(i); 
        } else {
            print(i + 1);
        }
    }
    return 0;
}

 

[POI2001]和平委员会

标签:lin   top   mes   委员会   blog   exit   总结   https   min   

原文地址:https://www.cnblogs.com/zcr-blog/p/12860413.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!