HDU - 3062

2-sat模板题

矛盾体之间错开建边,最后缩点,看同一个夫妻在一个联通块中。

#include <bits/stdc++.h>
#define inf 23333333333333
#define N 3010
#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(a2);in(c1);in(c2);
            G.push(2*a1+c1,2*a2+1-c2);
            G.push(2*a2+c2,2*a1+1-c1);
        }
        For(i,0,2*n-1)
            if(!G.dfn[i]) G.tarjan(i);
        flag=0;
        for(int i=0;i<=2*n-2;i+=2){
            if(G.c[i]==G.c[i+1]){
                flag=1;
                break;
            }
        }
        if(flag) puts("NO");
        else puts("YES");
    }   
    return 0;
}

 

posted @ 2020-08-04 10:18  WeiAR  阅读(105)  评论(0编辑  收藏  举报