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 }
 

原文地址:https://www.cnblogs.com/acSzz/p/2672500.html