2-SAT

struct node {
    int to, net;
}edge[maxn*4];

int head[maxn*2], cnt;
int dfn[maxn*2], low[maxn*2], ins[maxn*2];
int dfsclock;
int scnt;
int color[maxn*2];
stack<int> stk;
//解决逻辑类问题,可将每个点化为i,i’( i + n ),i为1,i’为0。
//如若选i就不能选j,由i向j’连边
//i^j == 1 (i-->j’; j-->i’)
//i^j == 0 (i-->j; j-->i)
//i|j == 1 (i-->j’; j-->i’; i’-->j; j’-->i)
//i必须选 (i-->i’)
void addedge(int u, int v) {
    edge[cnt] = (node){v, head[u]};
    head[u] = cnt++;
}
void tarjan(int pos) {
    low[pos] = dfn[pos] = ++dfsclock;
    stk.push(pos);
    ins[pos] = 1;
    for(int i = head[pos]; i != -1; i = edge[i].net) {
        int to = edge[i].to;
        if(!dfn[to]) {
            tarjan(to);
            low[pos] = min(low[pos], low[to]);
        }
        else if(ins[to]) low[pos] = min(low[pos], dfn[to]);
    }
    if(low[pos] == dfn[pos]) {
        ++scnt;
        do {
            color[pos] = scnt;
            pos = stk.top();
            stk.pop();
            ins[pos] = 0;
        } while(low[pos] != dfn[pos]);
    }
}

int main() {
    ios();
    int n, m;
    cin >> n >> m;
    rep(i, 0, (n << 1)) head[i] = -1;
    rep(i, 1, m) {
        int u, a, v, b;
        cin >> u >> a >> v >> b;
        addedge(u + n*(a ^ 1), v + n*(b & 1));
        addedge(v + n*(b ^ 1), u +  n*(a & 1));
    }
    rep(i, 1, (n << 1)) {
        if(!dfn[i]) tarjan(i);
    }
    rep(i, 1, n) {
        if(color[i] == color[i + n]) {
            puts("IMPOSSIBLE");
            return 0;
        }
    }
    puts("POSSIBLE");
    rep(i, 1, n) {
        cout << (color[i] > color[i + n]);
        if(i == n) cout << endl;
        else cout << ' ';
    }
    return 0;
}

 

//解决逻辑类问题,可将每个点化为ii( i + n )i1i0

//如若选i就不能选j,由ij连边

//i^j == 1 (i-->j; j-->i)

//i^j == 0 (i-->j; j-->i)

//i|j == 1 (i-->j’; j-->i’; i’-->j; j’-->i)

//i必须选 (i-->i’)

posted @ 2020-09-30 19:55  Ruby·Z  阅读(46)  评论(0)    收藏  举报