POJ3678——Katu Puzzle

来源:互联网 发布:单片机原理及应用 编辑:程序博客网 时间:2024/05/17 23:59

Description

Katu Puzzle is presented as a directed graph G(V, E) with each edgee(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integerc (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertexVi a value Xi (0 ≤ Xi ≤ 1) such that for each edgee(a, b) labeled by op and c, the following formula holds:

 Xa op Xb = c

The calculating rules are:

AND01000101OR01001111XOR01001110

Given a Katu Puzzle, your task is to determine whether it is solvable.

Input

The first line contains two integers N (1 ≤ N ≤ 1000) and M,(0 ≤ M ≤ 1,000,000) indicating the number of vertices and edges.
The following M lines contain three integers a (0 ≤ a <N), b(0 ≤ b < N), c and an operator op each, describing the edges.

Output

Output a line containing "YES" or "NO".

Sample Input

4 40 1 1 AND1 2 1 OR3 2 0 AND3 0 0 XOR

Sample Output

YES

Hint

X0 = 1, X1 = 1,X2 = 0, X3 = 1.

Source


题目很简单,但是我建图还是建错了,后来看了别人的,才知道当a&b==1和a|b==0时,必须建立  (~a -> a)这样的边,比如a&b==1,a和b显然是取 1的,那么如果一旦a取了0,根据有边(~a->a), 马上推出矛盾


#include<stdio.h>#include<string.h>const int N=2010;const int maxm=9000010;struct node{int to;int next;}edge[maxm];char str[10];int head[N];int tot,index,sccnum,top;int DFN[N],low[N];int Stack[N];bool instack[N];int block[N];int min(int a,int b){return a<b?a:b;}void addedge(int from,int to){edge[tot].to=to;edge[tot].next=head[from];head[from]=tot++;}void tarjan(int u){DFN[u]=low[u]=++index;Stack[++top]=u;instack[u]=1;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(!DFN[v]){tarjan(v);low[u]=min(low[v],low[u]);}else if(instack[v])low[u]=min(low[u],DFN[v]);}if(DFN[u]==low[u]){sccnum++;int v;do{v=Stack[top--];instack[v]=0;block[v]=sccnum;}while(v!=u);}}void init(){memset(DFN,0,sizeof(DFN));memset(low,0,sizeof(low));memset(head,-1,sizeof(head));memset(instack,0,sizeof(instack));tot=0;index=0;sccnum=0;}int main(){int n,m;while(~scanf("%d%d",&n,&m)){init();int a,b,c;for(int i=1;i<=m;i++){scanf("%d%d%d%s",&a,&b,&c,str);if(!strcmp(str,"AND") && c){//and运算addedge(a+n,b+n);addedge(b+n,a+n);addedge(a,a+n);addedge(b,b+n);}else if(!strcmp(str,"AND") && !c){addedge(a+n,b);addedge(b+n,a);}else if(!strcmp(str,"OR") && c){addedge(a,b+n);addedge(b,a+n);}else if(!strcmp(str,"OR") && !c){addedge(a,b);addedge(b,a);addedge(a+n,a);addedge(b+n,b);}else if(!strcmp(str,"XOR") && c){addedge(a,b+n);addedge(a+n,b);addedge(b,a+n);addedge(b+n,a);}else{addedge(a,b);addedge(b,a);addedge(a+n,b+n);addedge(b+n,a+n);}}for(int i=0;i<n+n;i++)if(!DFN[i])tarjan(i);bool flag=false;for(int i=0;i<n;i++)if(block[i]==block[i+n]){flag=true;printf("NO\n");break;}if(!flag)printf("YES\n");}return 0;}


0 0
原创粉丝点击