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 }
  • 相关阅读:
    linux驱动开发学习一:创建一个字符设备
    如何高效的对有序数组去重
    找到缺失的第一个正整数
    .NET不可变集合已经正式发布
    中国人唯一不认可的成功——就是家庭的和睦,人生的平淡【转】
    自己动手搭建 MongoDB 环境,并建立一个 .NET HelloWorld 程序测试
    ASP.NET MVC 中如何用自定义 Handler 来处理来自 AJAX 请求的 HttpRequestValidationException 错误
    自己动手搭建 Redis 环境,并建立一个 .NET HelloWorld 程序测试
    ServiceStack 介绍
    一步一步实战扩展 ASP.NET Route,实现小写 URL、个性化 URL
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13881042.html
Copyright © 2011-2022 走看看