zoukankan      html  css  js  c++  java
  • HDU3062 2sat

    2-sat

    初次接触2-sat。

    首先对于2-sat问题,可简化为:现在有N个党派,每个党派只有2名人员,从2者挑出一个,且某两个党派挑出来的人可能存在矛盾,这时不能同时选择他们。(引用对称性解决2-sat的ppt

    例如:(x1,x2),(y1,y2)为两个不同党派的人。

    若两两之间都没有矛盾,则do nothing

    若 x1-y1有矛盾,则他们不能同时被选择,所以 (x1,y2)是必选的,或者(x2,y1)是必选的。

    然后根据这条规律,tarjan+缩点,得到新的一张图,这张图没有环,若某个“点”中存在(x1,x2)(即:某个党派2个人同时出现在这个“点”中),这是就不能达到目标。

    反之成立。

    View Code
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<stack>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn = 2005;
     8 const int maxm = maxn*maxn;
     9 struct node{
    10     int u,next;
    11 }edge[ maxm ];
    12 int head[ maxn ],cnt;
    13 int vis[ maxn ],dfn[ maxn ],low[ maxn ],belong[ maxn ],id,cnt2;
    14 stack<int>s;
    15 void init(){
    16     memset( head,-1,sizeof( head ));
    17     cnt=0;
    18     id=0;
    19     while( !s.empty() ) s.pop();
    20     cnt2=0;
    21     memset( vis,0,sizeof( vis ));
    22     memset( dfn,-1,sizeof( dfn ));
    23     memset( low,-1,sizeof( low ));
    24     memset( belong,-1,sizeof( belong ));
    25 }
    26 void addedge( int a,int b ){
    27     edge[ cnt ].u=b;
    28     edge[ cnt ].next=head[ a ];
    29     head[ a ]=cnt++;
    30 }
    31 
    32 void tarjan( int now ){
    33     dfn[ now ]=low[ now ]=id++;
    34     vis[ now ]=1;
    35     s.push( now );
    36     for( int i=head[ now ];i!=-1;i=edge[ i ].next ){
    37         int next=edge[ i ].u;
    38         if( dfn[ next ]==-1 ){
    39             tarjan( next );
    40             low[ now ]=min( low[ now ],low[ next ] );
    41         }
    42         else if( vis[ next ]==1 ){
    43             low[ now ]=min( low[ now ],dfn[ next ] );
    44         }
    45     }
    46     if( low[ now ]==dfn[ now ] ){
    47         cnt2++;
    48         while( 1 ){
    49             int tmp;
    50             tmp=s.top(),s.pop();
    51             vis[ tmp ]=0;
    52             belong[ tmp ]=cnt2;
    53             if( tmp==now ) break;
    54         }
    55     }
    56 }
    57 int main(){
    58     int n,m;
    59     while( scanf("%d%d",&n,&m)==2 ){
    60         init();
    61         int a,b,c,d;
    62         while( m-- ){
    63             scanf("%d%d%d%d",&a,&b,&c,&d);
    64             addedge( 2*a+c,2*b+1-d );
    65             addedge( 2*b+d,2*a+1-c );
    66         }
    67         for( int i=0;i<2*n;i++ )
    68             if( dfn[ i ]==-1 )
    69                 tarjan( i );
    70         bool flag=true;
    71         for( int i=0;i<n;i++ ){
    72             if( belong[ 2*i ]==belong[ 2*i+1 ] )
    73             {
    74                 flag=false;
    75                 break;
    76             }
    77         }
    78         puts(flag?"YES":"NO");
    79         //if( flag==1 ) printf("NO\n");
    80         //else printf("YES\n");
    81     }
    82     return 0;
    83 }
    keep moving...
  • 相关阅读:
    git创建、删除分支
    Git 基础
    python pillow
    phantomjs 下载
    python3安装PIL
    selenium打开chrome时,出现 "您使用的是不受支持的命令行标记:--ignore-certificate-errors""
    chrome driver 下载
    go 单进程并发
    go 内嵌对象类型
    go 多态
  • 原文地址:https://www.cnblogs.com/xxx0624/p/2891857.html
Copyright © 2011-2022 走看看