2-sat模板

版权声明:本文为博主原创文章,未经博主允许必须转载。 https://blog.csdn.net/qq_35950004/article/details/82562478

不需要反向建边,不需要拓扑排序。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define maxn 2000005
using namespace std;

int n,m;
int info[maxn],Prev[maxn<<1],to[maxn<<1],cnt_e;
inline void Node(const int &u,const int &v){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v; }

int dfn[maxn],low[maxn],tot,c[maxn],scc,q[maxn],tp;
void dfs(int now)
{
    dfn[now] = low[now] = ++tot;
    q[tp++] = now;
    for(int i=info[now];i;i=Prev[i])
        if(!dfn[to[i]]) dfs(to[i]) , low[now] = min(low[now] , low[to[i]]);
        else if(!c[to[i]]) low[now] = min(low[now] , dfn[to[i]]);
    if(dfn[now] == low[now])
    {
        int tmp = -1; scc++;
        for(;tmp != now;)
            c[tmp = q[--tp]] = scc;
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1,a,b,u,v;i<=m;i++)
    {       
        scanf("%d%d%d%d",&a,&u,&b,&v);
        Node(a<<1|(!u) , b<<1|v);
        Node(b<<1|(!v) , a<<1|u);
    }

    for(int i=2;i<=(n<<1|1);i++) if(!dfn[i]) dfs(i);
    for(int i=1;i<=n;i++) if(c[i<<1]==c[i<<1|1]){ puts("IMPOSSIBLE");return 0; } 
    puts("POSSIBLE");
    for(int i=1;i<n;i++)
        if(c[i<<1] < c[i<<1|1]) printf("0 ");
        else printf("1 ");
    if(c[n<<1] < c[n<<1|1]) printf("0\n");
    else printf("1\n");
}

猜你喜欢

转载自blog.csdn.net/qq_35950004/article/details/82562478