P4782 【模板】2-SAT 问题

https://www.luogu.org/problemnew/show/P4782

链接

https://www.luogu.org/problemnew/show/P4782

思路

选a就必须选b
好像是要建反边,tarjan,tarjan的染色省去拓扑排序
拓扑排序我也感觉跟贪心似的

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2e6+7;
int read() {
    int x=0,f=1;char s=getchar();
    for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    return x*f;
}
int n,m;
int dfn[N],low[N],stak[N],top,vis[N],belong[N],cnt;
struct node {
    int v,nxt,q;
}e[N<<1];
int head[N<<1],tot;
void add(int u,int v) {
    e[++tot].v=v;
    e[tot].nxt=head[u];
    head[u]=tot;
}
void tarjan(int u) {
    dfn[u]=low[u]=++cnt;
    stak[++top]=u;
    vis[u]=1;
    for(int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if(!dfn[v]) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        } else if(vis[v]) {
            low[u]=min(low[u],dfn[v]);
        }
    }
    if(low[u]==dfn[u]) {
        belong[0]++;
        while(stak[top]!=u) {
            vis[stak[top]]=0;
            belong[stak[top]]=belong[0];
            top--;
        }
        vis[u]=0;
        belong[u]=belong[0];
        top--;
    }
}
int main() {
    n=read(),m=read();
    for(int k=1;k<=m;++k) {
        int i=read(),x=read(),j=read(),y=read();
//		add(n*(x^1)+i,n*y+j);
//		add(n*(y^1)+j,n*x+i);
        add(i + n * x,(j + n * (y ^ 1)));
        add(j + n * y,(i + n * (x ^ 1)));
    }
    for(int i=1;i<=n*2;++i)
        if(!dfn[i]) tarjan(i);
    for(int i=1;i<=n;++i) {
        if(belong[i]==belong[i+n]) {
            puts("IMPOSSIBLE");
            return 0;
        }
    }
    puts("POSSIBLE");
    for(int i=1;i<=n;++i) printf("%d ",(belong[i]<belong[i+n]));
    return 0;
}

原文地址:https://www.cnblogs.com/dsrdsr/p/10408071.html