• poj 3678 Katu Puzzle (2sat)


    http://poj.org/problem?id=3678

    题意:

    一些点,点的取值可以是0或者1,没有告诉你具体取值。

    一些边,有权值,有运算方式(并,或,异或),要求和这条边相连的两个点经过边上的运算后的结果是边的权值。

    问你有没有可能把每个点赋值满足所有边的要求。

    解题报告:(找矛盾 。必须 关系)

                  a and b == 1,  这种情况a和b必须取1,所以连边a->a', b->b'.
                  a and b == 0,  这种情况a和b不能同时为1,所以连边a'->b, b'->a.
                  a or b == 1,    这种情况a和b不能同时为0,所以连边a->b', b->a'.
                  a or b == 0,    这种情况a和b必须同时为0,所以连边a'->a, b'->b.
                  a xor b == 1,  这种情况a和b取值要相反,所以连边a->b', a'->b, b->a', b'->a.
                  a xor b == 0,  这种情况a和b取值要相同,所以连边a->b, b->a, a'->b', b'->a'.

    不能为0的处理时:如果i取0,那么i就要取1.

    原理 http://blog.sina.com.cn/s/blog_68629c7701010gf1.html

    即:i -> i + n。

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cmath>
      4 #include<iostream>
      5 #include<algorithm>
      6 #include<set>
      7 #include<map>
      8 #include<queue>
      9 #include<vector>
     10 #include<string>
     11 #define Min(a,b) a<b?a:b
     12 #define Max(a,b) a>b?a:b
     13 #define CL(a,num) memset(a,num,sizeof(a));
     14 #define eps  1e-12
     15 #define inf 100000000
     16 #define mx 1<<60
     17 #define ll   __int64
     18 const double pi  = acos(-1.0);
     19 const int maxn = 3000;
     20 using namespace std;
     21 int  top,num,bcnt,belong[maxn],instack[maxn],stack[maxn],dfn[maxn],low[maxn];
     22 int n ,m;
     23 
     24 struct pnode
     25 {
     26     int to;
     27     int next;
     28 }p[3000000];
     29 
     30 int cnt ,next[maxn];
     31 void add(int u,int v)
     32 {
     33     p[cnt].to = v;
     34     p[cnt].next  = next[u];
     35     next[u] = cnt++;
     36 
     37 }
     38 void tarjan(int i)
     39 {
     40     int j,k;
     41     dfn[i] = low[i] = ++num;
     42     stack[++top] = i;
     43     instack[i] = 1;
     44     for(k = next[i] ; k != -1;k = p[k].next)
     45     {
     46 
     47          j = p[k].to ;
     48         if(!dfn[j])
     49         {
     50             tarjan(j);
     51             if(low[j] < low[i]) low[i] = low[j] ;
     52         }
     53         else
     54         {
     55             if(instack[j] && dfn[j] < low[i]) low[i] = dfn[j] ;
     56         }
     57 
     58     }
     59     if(dfn[i] == low[i])
     60     {
     61         bcnt++;
     62         do
     63         {
     64             j = stack[top--];
     65             instack[j] = 0 ;
     66             belong[j] = bcnt ;
     67         }while(j != i);
     68     }
     69 }
     70 void solve()
     71 {
     72     int i, l;
     73     for(i =0 ; i <= n*2;i++)
     74     {
     75         dfn[i] = low[i] = instack[i] = stack[i] = belong[i] = 0;
     76     }
     77     top = bcnt = num = 0;
     78     for(i = 0 ; i < n*2;i++)
     79     {
     80         if(!dfn[i])tarjan(i);
     81     }
     82     bool f = true ;
     83     for(i = 0 ;  i < n;i++)
     84     {
     85 
     86         if(belong[i] == belong[i+n])
     87         {
     88 
     89             f = false ;
     90             break ;
     91         }
     92     }
     93 
     94     if(f) printf("YES\n");
     95     else
     96       printf("NO\n");
     97 }
     98 void init()
     99 {
    100     CL(next,-1);
    101     cnt = 0 ;
    102 
    103 }
    104 int main()
    105 {
    106     int i,j,a,b,c;
    107     char str[4] ;
    108     //freopen("data.txt","r",stdin) ;
    109 
    110    while(scanf("%d%d",&n,&m)!=EOF)
    111    {
    112        init() ;
    113        for(i = 0 ;i< m;i++)
    114        {
    115            scanf("%d %d %d %s",&a,&b,&c,str);
    116            if(str[0]=='A')
    117            {
    118                if(c == 0)
    119                {
    120                    add(a + n,b );
    121                    add(b+n,a) ;
    122 
    123               }
    124                else
    125                {
    126                    add(a + n,b + n);
    127                    add(b + n,a+n);
    128                    add(a,a+n);//注意这
    129                    add(b,b+n);
    130 
    131 
    132 
    133                }
    134 
    135            }
    136            if(str[0] == 'O')
    137            {
    138                if(c == 0)
    139                {
    140                    add(a ,b);
    141                    add(b,a);
    142                    add(a + n,a);//注意这
    143                    add(b+n,b) ;
    144 
    145 
    146 
    147 
    148 
    149                }
    150                else
    151                {
    152                    add(a,b + n);
    153 
    154                    add(b,a+n);
    155 
    156 
    157 
    158 
    159 
    160                }
    161            }
    162            if(str[0] == 'X')
    163            {
    164                if(c == 0)
    165                {
    166                    add(a ,b);
    167                    add(b,a);
    168                    add(a + n,b+ n);
    169                    add(b + n,a+n);
    170 
    171 
    172                }
    173                else
    174                {
    175                    add(a,b + n);
    176                    add(b + n,a);
    177                    add(a+n,b );
    178                    add(b,a+n);
    179 
    180 
    181                }
    182            }
    183        }
    184        solve() ;
    185    }
    186 }
     

  • 相关阅读:
    转载文章----.NET 框架浅析
    转载文章----IL反编译利器——Ildasm.exe和Reflector.exe:
    转载文章----初识Ildasm.exe——IL反编译的实用工具
    北航物理实验
    计算机组成原理往年试题以及答案(tzf!!!)
    Java 往年试卷参考答案!!!
    算法导论期末考试英文练习题带答案!!!
    算法导论( FFT & 自动机 & 最优二叉搜索树 !!!)
    Java部分总结图片版2(已加上原图链接!!!)
    Java部分总结图片版(已经加上原图链接下载!!!)
  • 原文地址:https://www.cnblogs.com/acSzz/p/2672500.html
Copyright © 2020-2023  润新知