2-SAT( tarjan应用 )

大佬博客:here

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 模板题目:P4782 【模板】2-SAT 问题

 

 AC_Code:

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef long double ld;
  5 #define endl '\n'
  6 const int inf=0x3f3f3f3f;
  7 const int maxn=2e6+10;
  8 const int maxm=4e6+10;
  9 
 10 struct node{
 11     int to,nxt;
 12 }e[maxm];
 13 
 14 int head[maxn],tot;
 15 int dfn[maxn],low[maxn],cnt;    //dfn[i]:i被访问的时间点,low[i]:通过有向边可回溯到的最早的时间点 cnt为时间戳
 16 int _stack[maxn],top;
 17 bool instack[maxn];
 18 int belong[maxn],scnt;          //belong[i]:i所属的强联通分量的编号,scnt:记录强联通分量的个数,以及每一个强联通分量的个数
 19 int n,m;
 20 
 21 void init(){
 22     memset(head,-1,sizeof(head)); tot=0;
 23     memset(instack,false,sizeof(instack)); top=0;
 24     memset(dfn,0,sizeof(dfn)); cnt=0;
 25     scnt=0;
 26 }
 27 
 28 void addedge(int u,int v){
 29     e[tot].to=v; e[tot].nxt=head[u]; head[u]=tot++;
 30 }
 31 
 32 void tarjan_dfs(int u){
 33     dfn[u] = low[u] = ++cnt;
 34     instack[u]=true;    //标记u已经在栈中
 35     _stack[top++]=u;    //u入栈
 36     for(int i=head[u];~i;i=e[i].nxt){
 37         int to=e[i].to;
 38         if( !dfn[to] ){ //未被访问,继续向下dfs
 39             tarjan_dfs(to);
 40            if( low[u]>low[to] ) low[u]=low[to]; //更新节点u所能到达的最小时间
 41         }
 42         else if( instack[to] && low[u]>dfn[to]){    //如果to已经在栈中
 43             low[u]=dfn[to];
 44         }
 45     }
 46     if( low[u]==dfn[u] ){   //如果节点u是强连通分量的根
 47         scnt++; //连通分量个数加1
 48         while(1){
 49             int v=_stack[--top];    //退栈
 50 //            printf("%d-",v);        //输出
 51             instack[v]=false;       //标记不在栈中
 52             belong[v]=scnt;
 53             if( v==u ) break;
 54         }
 55 //        printf("\n");
 56     }
 57 }
 58 
 59 int main()
 60 {
 61     init();
 62     scanf("%d%d",&n,&m);
 63     for(int i=1; i<=m; i++){
 64         int a,b,x,y; cin>>a>>x; cin>>b>>y;
 65         if( x && y ){       // a∨b : ¬a→b ∧ ¬b→a
 66             addedge(a+n,b);
 67             addedge(b+n,a);
 68         }
 69         else if( !x && y ){ // ¬a∨b : a→b ∧ ¬b→¬a
 70             addedge(a,b);
 71             addedge(b+n,a+n);
 72         }
 73         else if(x&&!y){     // ¬b∨a : b→a ∧ ¬a→¬b
 74             addedge(b,a);
 75             addedge(a+n,b+n);
 76         }
 77         else if(!x&&!y){    // ¬a∨¬b : a→¬b ∧ b→¬a
 78             addedge(a,b+n);
 79             addedge(b,a+n);
 80         }
 81     }
 82 
 83     for(int i=1;i<=2*n;i++){
 84         if( !dfn[i] ){
 85             tarjan_dfs(i);
 86         }
 87     }
 88 
 89     for(int i=1;i<=n;i++){
 90         if( belong[i]==belong[i+n] ){
 91             printf("IMPOSSIBLE\n");
 92             return 0;
 93         }
 94     }
 95 
 96     printf("POSSIBLE\n");
 97     for(int i=1;i<=n;i++){
 98         if( belong[i]<belong[i+n] ){
 99             if( i==1 ) printf("1");
100             else printf(" 1");
101         }
102         else{
103             if( i==1 ) printf("0");
104             else printf(" 0");
105         }
106     }
107     printf("\n");
108     return 0;
109 }

 

posted @ 2020-10-26 20:44  swsyya  阅读(130)  评论(0编辑  收藏  举报

回到顶部