• P4782 【模板】2-SAT 问题


    如果 I 和 I’ 在同一强连通分量中,那么肯定 I 能到达 i’ , I’ 能到达 i,所以无解。
    如果 I 和 I’ 不在同一强连通分量中,那么对缩点后的新图进行拓扑排序,我们选择拓扑序大的点,而拓扑序大的点肯定是到达不了拓扑序小的点的,根据DFS做法中的证明,我们可以证明我们的选择一定合法。
    而我们缩点后,如果 I 能到达 i’,则 I 所属的新点标号一定大于I’(仔细思考),那么我们只需要比较 I 和 i’ 所属的新点标号,选择较大的点即可,这样就不用再进行拓扑排序了。

    #include <bits/stdc++.h>
    #define inf 23333333333333
    #define N 2000010
    #define p(a) putchar(a)
    #define For(i,a,b) for(int i=a;i<=b;++i)
    
    using namespace std;
    int n,m,a1,a2,c1,c2,flag;
    void in(int &x){
        int y=1;char c=getchar();x=0;
        while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
        while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
        x*=y;
    }
    void o(int x){
        if(x<0){p('-');x=-x;}
        if(x>9)o(x/10);
        p(x%10+'0');
    }
    
    struct Graph{
        int cnt,col,now;
        int d[N],low[N],dfn[N],c[N];
        bool vis[N];
        stack<int>s;
        struct node{
            int n;
            node *next;
        }*e[N];
        void init(){
            cnt=col=0;
            For(i,0,2*n+5) e[i]=0;
            memset(d,0,sizeof d);
            memset(low,0,sizeof low);
            memset(dfn,0,sizeof dfn);
            memset(c,0,sizeof c);
            memset(vis,0,sizeof vis);
            while(!s.empty()) s.pop();
        }
        void push(int x,int y){
            node *p;
            p=new node();
            p->n=y;
            if(e[x]==0)
                e[x]=p;
            else{
                p->next=e[x]->next;
                e[x]->next=p;
            }
        }
    
        void tarjan(int x){
            dfn[x]=low[x]=++cnt;
            vis[x]=1;
            s.push(x);
            for(node *i=e[x];i;i=i->next){
                if(!dfn[i->n]){
                    tarjan(i->n);
                    low[x]=min(low[x],low[i->n]);
                }
                else
                    if(vis[i->n])
                        low[x]=min(low[x],dfn[i->n]);
            }
            if(low[x]==dfn[x]){
                col++;
                do{
                    now=s.top();
                    c[now]=col;
                    s.pop();
                    vis[now]=0;
                }while(x!=now);
            }
        }
    }G;
    
    signed main(){
        while(cin>>n>>m){
            G.init();
            For(i,1,m){
                in(a1);in(c1);in(a2);in(c2);
                G.push(2*a1-c1,2*a2+c2-1);
                G.push(2*a2-c2,2*a1+c1-1);
            }
            For(i,1,2*n)
                if(!G.dfn[i]) G.tarjan(i);
            flag=0;
            for(int i=1;i<=2*n;i+=2){
                if(G.c[i]==G.c[i+1]){
                    flag=1;
                    break;
                }
            }
            if(flag) puts("IMPOSSIBLE");
            else{
                puts("POSSIBLE");
                for(int i=1;i<=2*n;i+=2){
                    if(G.c[i]>G.c[i+1]){
                        o(1);
                    }else{
                        o(0);
                    }
                    p(' ');
                }
                p('
    ');
            }
        }   
        return 0;
    }
  • 相关阅读:
    vue element-admin 清空校验
    vue+elementui 动态改变表单必填项
    什么是中台
    项目中遇到的一道算法题
    【解决】Word中公式突然乱码
    【解决】MATLAB报错:此上下文中不支持函数定义,请在代码文件中创建函数。
    【解决】Word打印成PDF出错:%%[ ProductName: Distiller ]%%
    Bike Sharing Analysis(二)- 假设检验方法
    Bike Sharing Analysis(一)- 探索数据
    Spark Structured Streaming(二)实战
  • 原文地址:https://www.cnblogs.com/war1111/p/13432094.html
Copyright © 2020-2023  润新知