zoukankan      html  css  js  c++  java
  • 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 '
    '
      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("
    ");
     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
    ");
     92             return 0;
     93         }
     94     }
     95 
     96     printf("POSSIBLE
    ");
     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("
    ");
    108     return 0;
    109 }
  • 相关阅读:
    Windows10 Docker 安装 dotnet core sdk 超时
    解决 jQuery-datepicker无法弹出日期的问题
    SQL2008 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。
    “entities.LastOrDefault()”引发了类型“System.NotSupportedException”的异常
    快速开发平台
    快速设计ComboBox下拉框
    流程设计-流程模式
    流程设计-流程工具
    快速开发一款APP
    SDP开发
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13881042.html
Copyright © 2011-2022 走看看