2-sat笔记


P4782 【模板】2-SAT 问题

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;
const int N = 2e6 + 9;
const int M = 2e6 + 9;
int h[N], ne[M], to[M], idx;
void add(int u, int v) {
    ne[idx] = h[u], to[idx] = v, h[u] = idx++;
}
int dfn[N], low[N], times;
int sz[N], id[N], scc_cnt;
int stk[N], instk[N], top;

void tarjan(int u) {
    dfn[u] = low[u] = times++;
    stk[++top] = u;
    instk[u]= 1;
    for (int i = h[u]; ~i; i = ne[i]) {
        int v = to[i];
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        } else if (instk[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if (low[u] == dfn[u]){
        scc_cnt++;
        while (1) {
            int v = stk[top];
            top--;
            instk[v] = 0;
            id[v] = scc_cnt;
            sz[scc_cnt] ++;
            if (v == u)break;
        }
    }
}
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    memset(h, -1, sizeof h);idx = 0;
    for (int i = 1; i <= m; i ++) {
        int u, x, v, y;
        scanf("%d%d%d%d", &u, &x, &v, &y);
        add(u + (x^1)*n, v + y * n);
        add(v + (y^1)*n, u + x * n);
    }
    for (int i = 1; i <= 2 * n; i ++) {
        if (!dfn[i]) tarjan(i);
    }
    for (int i = 1; i <= n; i ++) {
        if (id[i] == id[i + n]) {
            puts("IMPOSSIBLE");
            return 0;
        }
    }
    puts("POSSIBLE");
    for (int i = 1; i <= n; i ++) {
        if (id[i] > id[i  + n])printf("1 ");
        else printf("0 ");
    }
}
posted @ 2021-04-10 21:46  u_yan  阅读(27)  评论(0编辑  收藏  举报