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

2-sat板子

时间:2019-09-21 20:54:54      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:add   oid   void   ons   ack   --   tarjan   return   pac   

namespace TwoSat {
    const int N = 2007;
    int dfn[N << 1], low[N << 1], belong[N << 1], idx;
    int in[N << 1], ou[N << 1], stk[N << 1], top;
    int ans[N], scc_cnt, sign, n;
    vector<int> G[N << 1];
    void init(int _n) {
        n = _n;
        for(int i = 0; i <= n * 2 + 1; i++) {
            belong[i] = dfn[i] = low[i] = 0;
            stk[i] = in[i] = ou[i] = 0;
            G[i].clear();
        }
        scc_cnt = idx = top = sign = 0;
    }
    void addEdge(int u, int v) {
        G[u].push_back(v);
    }
    void tarjan(int u) {
        stk[++top] = u; in[u] = 1;
        dfn[u] = ++idx; low[u] = idx;
        for(auto &v : G[u]) {
            if(dfn[v] == 0) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if(in[v]) {
                low[u] = min(low[u], dfn[v]);
            }
        }
        if(dfn[u] == low[u]) {
            scc_cnt++;
            while(1) {
                int v = stk[top--];
                belong[v] = scc_cnt;
                in[v] = 0;
                ou[v] = ++sign;
                if(v == u) break;
            }
        }
    }
    // if ans == 0, choose i, else choose i + n
    int solve() {
        for(int i = 1; i <= n * 2; i++) if(!dfn[i]) tarjan(i);
        for(int i = 1; i <= n; i++) if(belong[i] == belong[i + n]) return 0;
        for(int i = 1; i <= n; i++) ans[i] = ou[i] > ou[i + n];
        return 1;
    }
}

 

2-sat板子

标签:add   oid   void   ons   ack   --   tarjan   return   pac   

原文地址:https://www.cnblogs.com/CJLHY/p/11564487.html

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