2-sat 问题 模板

class sat
{
    public:
    int n,m,len,col,tot,ror;
    int dfn[N],low[N],pre[N];
    int stage[N],Stack[N];
    bool mark[N];
    int color[N],cont[N];
    int fa[N];
    vector<int>vec[N];

    struct node{
        int y,pre;
    };
    node a[90010];
    void init()
    {
        len=1; col=0; tot=1; ror=1;
        memset(dfn,0,sizeof(dfn));
        memset(pre,-1,sizeof(pre));
        memset(mark,false,sizeof(mark));
        memset(stage,0,sizeof(stage));
    }
    void addpage(int s,int t)
    {
        a[len].y=t;
        a[len].pre=pre[s];
        pre[s]=len++;
    }
    void dfs(int x)
    {
        Stack[ror++]=x;
        dfn[x]=low[x]=tot++;
        mark[x]=true;
        for(int i=pre[x]; i!=-1; i=a[i].pre)
        {
            int y=a[i].y;
            if(!dfn[y])
            {
                dfs(y);
                low[x]=min(low[x],low[y]);
            }else if(mark[y]==true)
                low[x]=min(low[x],low[y]);
        }
        int i;
        if(dfn[x]==low[x])
        {
            ++col;
            do{
                i=Stack[--ror];
                mark[i]=false;
                stage[i]=col;
            }while(i!=x);
        }
    }
    bool fail()//判断是否有解
    {
        repf(i,1,n)//n只有一半,怎样判断使情况而定的
            if(stage[2*i-1]==stage[2*i])
                return false;
        return true;
    }
    void work()//拓扑排序和染色的
    {
        memset(color,0,sizeof(color));
        repf(i,1,n*2) vec[i].clear();
        memset(cont,0,sizeof(cont));
        repf(i,1,2*n)
            for(int j=pre[i]; j!=-1; j=a[j].pre)
            {
                if(stage[i]!=stage[a[j].y])
                {
                    vec[stage[a[j].y]].push_back(stage[i]);
                    cont[stage[i]]++;
                }
            }
        rep(i,n)
         fa[stage[2*i-1]]=stage[2*i],
            fa[stage[2*i]]=stage[2*i-1];
        queue<int>q;//队列染色,符合大部分的
        repf(i,1,col)
         if(cont[i]==0) q.push(i);
        while(!q.empty())
        {
            int x=q.front(); q.pop();
            if(color[x]==0)
                color[x]=1,color[fa[x]]=2;
            rep(i,vec[x].size())
            {
                int y=vec[x][i];
                cont[y]--;
                if(cont[y]==0) q.push(y);
            }
        }
    }
};
sat sa;




 

你可能感兴趣的:(2-sat 问题 模板)