Katu Puzzle

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

题意:给你一些数,然后这些要么是0要么是1,然后回给出一些数之间的and,or,xor的值,问你是否存在一组解。

题解:2-sat的一道很好的题目。能很好训练建边的思想。建边如下。

and==1: 说明 a,b必须选,就是必须都是1,所以a->~a,b->~b;

ans==0,说明 a,b不能同时都选,那么选择了~a就只能选择b,选择了~b就只能选择a;所以有边,~a-->b,~b->a;

or==1说明至少有一个是1 ,至少取一个,a-->~b;b-->~a;

or==0说明都不取, ~a->a;~b->b;

xor==1建边 x->~y,y->~x,~y->x,~x->y (两个数必须不同)

xor==0 建边 x->y,y->x,~x->~y,~y->~x (两个数必须相同)

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 using namespace std;
  6 const int N=1e5+10;
  7 const int M=1e7+100;
  8 struct Edge{
  9     int to,next;
 10 } edge[M];
 11 int  n,m,cnt,dep,top,atype;
 12 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],in[N],out[N],sum[N];
 13 //sum[i]记录第i个连通图的点的个数,in[i],out[i],表示缩点之后点的入度和初度。
 14 void init(){
 15       cnt=dep=top=atype=0;
 16     memset(head,-1,sizeof(head));
 17     memset(dfn,0,sizeof(dfn));
 18     memset(low,0,sizeof(low));
 19     memset(vis,0,sizeof(vis));
 20     memset(belong,0,sizeof(belong));
 21     memset(in,0,sizeof(in));
 22     memset(out,0,sizeof(out));
 23     memset(sum,0,sizeof(sum));
 24 }
 25 void addedge(int u,int v){
 26     edge[cnt].to=v;
 27     edge[cnt].next=head[u];
 28     head[u]=cnt++;
 29 }
 30
 31 void Tarjan(int u){
 32     dfn[u]=low[u]=++dep;
 33     st[top++]=u;
 34     vis[u]=1;
 35     for(int i=head[u]; i!=-1; i=edge[i].next){
 36         int v=edge[i].to;
 37         if(!dfn[v]){
 38             Tarjan(v);
 39             low[u]=min(low[u],low[v]);
 40         }
 41         else if(vis[v]){
 42             low[u]=min(low[u],dfn[v]);
 43         }
 44     }
 45     int j;
 46     if(dfn[u]==low[u]){
 47         atype++;
 48         do{
 49             j=st[--top];
 50             belong[j]=atype;
 51             sum[atype]++;   //记录每个连通分量中点的个数
 52             vis[j]=0;
 53         }
 54         while(u!=j);
 55     }
 56 }
 57 char str[23];
 58 int u,v,w;
 59 int main(){
 60   while(~scanf("%d%d",&n,&m)){
 61         init();
 62       for(int i=1;i<=m;i++){
 63         scanf("%d%d%d%s",&u,&v,&w,str);
 64           u++;v++;
 65          if(str[0]==‘A‘){
 66             if(w==1){
 67                 addedge(u,u+n);
 68                 addedge(v,v+n);
 69             }
 70             else{
 71                 addedge(u+n,v);
 72                 addedge(v+n,u);
 73             }
 74          }
 75          else if(str[0]==‘O‘){
 76             if(w==1){
 77             addedge(u,v+n);
 78             addedge(v,u+n);
 79             }
 80             else {
 81                 addedge(u+n,u);
 82                 addedge(v+n,v);
 83             }
 84          }
 85          else if(str[0]==‘X‘){
 86             if(w==1){
 87               addedge(u,v+n);
 88               addedge(u+n,v);
 89               addedge(v+n,u);
 90               addedge(v,u+n);
 91             }
 92             else{
 93                 addedge(u,v);
 94                 addedge(v,u);
 95                 addedge(u+n,v+n);
 96                 addedge(v+n,u+n);
 97             }
 98          }
 99       }
100       for(int i=1;i<=2*n;i++)
101         if(!dfn[i])Tarjan(i);
102       bool flag=false;
103       for(int i=1;i<=n;i++){
104           if(belong[i]==belong[i+n]){
105             flag=true;
106             break;
107           }
108       }
109       if(flag)printf("NO\n");
110       else
111         printf("YES\n");
112   }
113 }

时间: 2024-10-13 14:51:38

Katu Puzzle的相关文章

POJ 3678 Katu Puzzle(2-sat 模板题)

题目链接:http://poj.org/problem?id=3678 Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each

POJ3678 Katu Puzzle

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9238   Accepted: 3436 Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c

[2-SAT] poj 3678 Katu Puzzle

题目链接: http://poj.org/problem?id=3678 Katu Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7888   Accepted: 2888 Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator 

poj 3678 Katu Puzzle(2-sat)

Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) s

Katu Puzzle (poj 3678 2-SAT)

Language: Default Katu Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8487   Accepted: 3149 Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR,

poj 3678 Katu Puzzle 2-SAT 建图入门

Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) s

POJ - 3678 - Katu Puzzle(2SAT)

链接: https://vjudge.net/problem/POJ-3678 题意: Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each ver

POJ3678.Katu Puzzle——2-sat裸题

http://poj.org/problem?id=3678 题目描述: n个变量,m组逻辑表达式,每个变量取1或取0,判断是否有解 分析: 每个变量两种状态,m种矛盾 构图建边 a表示元变量,a'表示反变量 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'->

【POJ】3678 Katu Puzzle

http://poj.org/problem?id=3678 题意:很幼稚的题目直接看英文题面= = #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <iostream> using namespace std; const int N=1000*2+10, M=N*N*4; struct E { int next, to; }