图论之2-sat模板

来源:互联网 发布:网络商品交易改革 编辑:程序博客网 时间:2024/05/31 19:57
#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<queue>#include<stack>using namespace std;int n;const int maxn=2011;struct Node{    int s,e;}Tim[2*maxn];vector<int>e[2*maxn];vector<int>e2[2*maxn];vector<int>ans;stack<int>st;int id,col;int dfn[2*maxn],low[2*maxn],flag[2*maxn], in[2*maxn];bool inst[2*maxn];int cf[2*maxn];//cf[x]保存的是和编号为 x 的连通分量矛盾的连通分量的编号int Col[2*maxn];//利用矛盾关系建图、缩点、反向建图、利用拓扑关系重新着色。void addedge(int u,int v){    e[u].push_back(v);}bool Judge(int x,int y){    if(Tim[x].e<=Tim[y].s||Tim[x].s>=Tim[y].e)return 1;    return 0;}void buildmap(){    for(int i=0;i<n;i++){        for(int j=0;j<n;j++){            if(i!=j){                if(!Judge(2*i,2*j))                    addedge(2*i,2*j+1);                if(!Judge(2*i,2*j+1))                    addedge(2*i,2*j);                if(!Judge(2*i+1,2*j))                    addedge(2*i+1,2*j+1);                if(!Judge(2*i+1,2*j+1))                    addedge(2*i+1,2*j);            }        }    } }void Tarjan(int u){    dfn[u]=low[u]=id++;    st.push(u);    inst[u]=1;    for(int i=0;i<e[u].size();i++){        int k=e[u][i];        if(dfn[k]==0){            Tarjan(k);            low[u]=std::min(low[u],low[k]);        }        else if(inst[k]){            low[u]=std::min(low[u],dfn[k]);        }    }    if(dfn[u]==low[u]){        while(1){            int x=st.top();            st.pop();            flag[x]=col;            inst[x]=0;            if(x==u)break;        }        col++;    }}int solve(){    for(int i=0;i<2*n;i++){        if(!dfn[i]){            Tarjan(i);        }    }    for(int i=0;i<2*n;i+=2){        if(flag[i]==flag[i^1])return 1;        cf[flag[i]]=flag[i^1];        cf[flag[i^1]]=flag[i];    }    return 0;}void Topsort(){    queue<int>q;    for(int i=1;i<col;i++){        if(in[i]==0)q.push(i);    }    while(!q.empty()){        int u=q.front();        q.pop();        if(Col[u]==0){            Col[u]=1;            Col[cf[u]]=-1;        }        for(int i=0;i<e2[u].size();i++){            int v=e2[u][i];            in[v]--;            if(in[v]==0)q.push(v);        }    }}void Getans(){    for(int i=0;i<2*n;i++){//建立反向图        for(int j=0;j<e[i].size();j++){            if(flag[i]!=flag[e[i][j]]){                e2[flag[e[i][j]]].push_back(flag[i]);                in[flag[i]]++;            }        }    }    Topsort();//求结果}void init(){    memset(dfn,0,sizeof(dfn));    memset(low,0,sizeof(low));    memset(flag,0,sizeof(flag));    memset(inst,0,sizeof(inst));}int main(){    init();    buildmap();    solve();    return 0;}

0 0