zoukankan      html  css  js  c++  java
  • 2-SAT求任意解模板

    int stk[N],vis[N],low[N],link[N],mark[N];
    int top,index,id,du[N];//记录入度数
    int pre[N],cnt,g[N];// g 用来记录topsort后的结果
    int g1[N]; //用来记录缩点后的每一个点所含的点
    
    
    void dfs(int s)
    {
        mark[s]=1;
        vis[s]=index++;
        low[s]=vis[s];
        stk[top++]=s;
        for(int p=pre[s];p!=-1;p=edge[p].next)
        {
            int v=edge[p].to;
            if(mark[v]==0) dfs(v);
            if(mark[v]==1) low[s]=min(low[s],low[v]);
        }
        if(low[s]==vis[s])
        {
            int tmp;
            id++;
            do
            {
                tmp=stk[top-1];
                link[tmp]=id;
                mark[tmp]=-1;
            }while(stk[--top]!=s);
        }
    }
    
    void add_edge(int u,int v)
    {
        edge[cnt].from=u;
        edge[cnt].to=v;
        edge[cnt].next=pre[u];
        pre[u]=cnt++;
    }
    
    void topsort()
    {
        memset(mark,0,sizeof(mark));
        top=0;
        int tcnt=0;
        for(int i=1;i<=id;i++)
            if(du[i]==0)
            {
                mark[i]=1;
                stk[top++]=i;//把这个节点入栈
                g[tcnt++]=i;
            }
        while(top!=0)
        {
            int cur=stk[--top];
            for(int p=pre[cur];p!=-1;p=edge[p].next)
            {
                int v=edge[p].to;
                if(mark[v]==1) continue;
                du[v]--;
                if(du[v]==0)
                {
                    mark[v]=1;
                    stk[top++]=v;
                    g[tcnt++]=v;
                }
            }
        }
    
    }
    
    void dfs1(int s) //将所有不可能的情况标记
    {
        mark[s]=-1;
        for(int p=pre[s];p!=-1;p=edge[p].next)
        {
            int v=edge[p].to;
            dfs1(v);
        }
    }
    
    void sat2(int sn) //top 表示传入的点数。 其中要保证标号从0开始而且0和1是一组
    {
        top=index=id=0;
        memset(mark,0,sizeof(mark));
        for(int i=0;i<sn;i++)
            if(mark[i]==0)
                dfs(i);
        int flag=0;
        for(int i=0;i<sn;i+=2)
        {
            if(link[i]==link[i+1])
            {
                flag=1;
                break;
            }
        }
        if(flag)
        {
            /*  当不可行的时候输出 */
            printf("bad luck
    ");
        }
        else
        {
            /*  可行的时候输出 */
            printf("YES
    ");
    
            int tcnt=cnt;
            memset(g1,0,sizeof(g1));
            cnt=0;
            memset(pre,-1,sizeof(pre));
            for(int i=0;i<sn;i++)
            {
                g1[ link[i] ]=i;
            }
    
            memset(du,0,sizeof(du));
    
            for(int i=0;i<tcnt;i++)
            {
                int x=edge[i].from;
                int y=edge[i].to;
                if(link[x] != link[y])
                {
                    add_edge(link[y],link[x]);//建逆图
                    du[ link[x] ]++;
                }
            }
            topsort();
            memset(mark,0,sizeof(mark));
    
            for(int i=0;i<id;i++)
            {
                if(mark[ g[i] ]!=-1)//表示这个点可以选
                {
                    mark[ g[i] ]=1;
                    int key=g1[ g[i] ];
                    key=key^1;
                    key=link[key];
                    dfs1(key);
                }
            }
            /*   print  mark[ link[i] ]==1 的表示可选的 */
            
        }
    }
  • 相关阅读:
    Codeforces Round #131 (Div. 2) E. Relay Race dp
    Codeforces Round #130 (Div. 2) C
    Codeforces Round #130 (Div. 2) A. Dubstep
    UVA 11858 Frosh Week 逆序对统计
    UVA 11149 Power of Matrix 快速幂
    UVA 12382 Grid of Lamps 贪心
    POJ 3614 Sunscreen 贪心
    Codeforces Round #238 (Div. 2) D. Toy Sum 暴搜
    Codeforces Round #227 (Div. 2) E. George and Cards 线段树+set
    Codeforces Round #327 (Div. 2) E. Three States
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3350414.html
Copyright © 2011-2022 走看看