P4782-[模板]2-SAT问题【tarjan】
生活随笔
收集整理的這篇文章主要介紹了
P4782-[模板]2-SAT问题【tarjan】
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
題目鏈接:https://www.luogu.com.cn/problem/P4782
題目大意
給若干個條件限定為xi為a或xj為bx_i為a或x_j為bxi?為a或xj?為b。求構造一個序列xxx滿足所有條件
解題思路
我們對于每個xix_ixi?構造兩個點分別表示xix_ixi?為0/10/10/1。然后就開始對能夠確定的條件關系連邊。那么顯然有在一個強連通分量里的真假一定相等。也就是如果對于一個xix_ixi?的兩個點都在一個強連通里,那么就無解了。
而確定之后我們只需要根據拓撲序大小來確定真假即可。
時間復雜度O(n)O(n)O(n)
codecodecode
#include<cstdio> #include<cstring> #include<algorithm> #include<stack> using namespace std; const int N=2e6+10; struct node{int to,next; }a[N*2]; int n,m,tot,cnt,num,ls[N]; int dfn[N],low[N],color[N]; bool ins[N]; stack<int> S; void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return; } void tarjan(int x){dfn[x]=low[x]=++cnt;S.push(x);ins[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(!dfn[y])tarjan(y),low[x]=min(low[x],low[y]);else if(ins[y]) low[x]=min(low[x],dfn[y]);}if(low[x]==dfn[x]){++num;while(S.top()!=x){ins[S.top()]=0;color[S.top()]=num;S.pop();}color[S.top()]=num;ins[S.top()]=0;S.pop();}return; } int main() {scanf("%d%d",&n,&m);for(int k=1;k<=m;k++){int i,a,j,b;scanf("%d%d%d%d",&i,&a,&j,&b);addl(i+a*n,j+(!b)*n);addl(j+b*n,i+(!a)*n);}for(int i=1;i<=n*2;i++)if(!dfn[i])tarjan(i);for(int i=1;i<=n;i++)if(color[i]==color[i+n]){printf("IMPOSSIBLE");return 0;}printf("POSSIBLE\n");for(int i=1;i<=n;i++)printf("%d ",color[i]<color[i+n]); }總結
以上是生活随笔為你收集整理的P4782-[模板]2-SAT问题【tarjan】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络推广怎么做如何推广电脑
- 下一篇: POJ3678-Katu Puzzle【