Language: Default Katu Puzzle
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 Xa op Xb = c The calculating rules are:
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 4 0 1 1 AND 1 2 1 OR 3 2 0 AND 3 0 0 XOR Sample Output YES Hint X0 = 1, X1 = 1, X2 = 0, X3 = 1. Source |
题意:n个点给出m个关系(AND,OR,XOR),问是否存在解。
思路:2-SAT建图
a AND b = 1: ~x->x,~y->y (两个数必须全为1)
a AND b = 0: y->~x,x->~y (两个数至少有一个为0)
a OR b = 1:~x->y,~y->x (两个数至少有一个为1)
a OR b = 0: x->~x,y->~y (两个数必须全为0)
a XOR b = 1:x->~y,y->~x,~y->x,~x->y (两个数必须不同)
a XOR b = 0:x->y,y->x,~x->~y,~y->~x (两个数必须相同)
代码:
#include <iostream> #include <functional> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #pragma comment (linker,"/STACK:102400000,102400000") #define pi acos(-1.0) #define eps 1e-6 #define lson rt<<1,l,mid #define rson rt<<1|1,mid+1,r #define FRE(i,a,b) for(i = a; i <= b; i++) #define FREE(i,a,b) for(i = a; i >= b; i--) #define FRL(i,a,b) for(i = a; i < b; i++) #define FRLL(i,a,b) for(i = a; i > b; i--) #define mem(t, v) memset ((t) , v, sizeof(t)) #define sf(n) scanf("%d", &n) #define sff(a,b) scanf("%d %d", &a, &b) #define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c) #define pf printf #define DBG pf("Hi\n") typedef long long ll; using namespace std; #define INF 0x3f3f3f3f #define mod 1000000009 const int maxn = 1005; const int MAXN = 3005; const int MAXM = 1200010; const int N = 1005; struct Edge { int to,next; }edge[MAXM]; int tot,head[MAXN]; int Low[MAXN],DFN[MAXN],Stack[MAXN],Belong[MAXN]; bool Instack[MAXN]; int top,Index,scc; int n,m; char str[10]; void init() { tot=0; memset(head,-1,sizeof(head)); } void addedge(int u,int v) { edge[tot].to=v; edge[tot].next=head[u]; head[u]=tot++; } void Tarjan(int u) { int v; Low[u]=DFN[u]=++Index; Stack[top++]=u; Instack[u]=true; for (int i=head[u];~i;i=edge[i].next) { v=edge[i].to; if (!DFN[v]) { Tarjan(v); if (Low[u]>Low[v]) Low[u]=Low[v]; } else if (Instack[v]&&Low[u]>DFN[v]) Low[u]=DFN[v]; } if (Low[u]==DFN[u]) { ++scc; do{ v=Stack[--top]; Instack[v]=false; Belong[v]=scc; }while (v!=u); } return ; } bool solvable(int n) { memset(DFN,0,sizeof(DFN)); memset(Instack,false,sizeof(Instack)); Index=scc=top=0; for (int i=0;i<n;i++) if (!DFN[i]) Tarjan(i); for (int i=0;i<n;i+=2) { if (Belong[i]==Belong[i^1]) return false; } return true; } int main() { #ifndef ONLINE_JUDGE freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin); #endif int i,j,a,b,c; scanf("%d%d",&n,&m); init(); for (i=0;i<m;i++) { scanf("%d%d%d %s",&a,&b,&c,str); if (strcmp(str,"OR")==0) { if (c==0) { addedge(2*a,2*a+1); addedge(2*b,2*b+1); } else { addedge(2*a+1,2*b); addedge(2*b+1,2*a); } } else if (strcmp(str,"AND")==0) { if (c==0) { addedge(2*a,2*b+1); addedge(2*b,2*a+1); } else { addedge(2*a+1,2*a); addedge(2*b+1,2*b); } } else { if (c==0) { addedge(2*a,2*b); addedge(2*a+1,2*b+1); addedge(2*b,2*a); addedge(2*b+1,2*a+1); } else { addedge(2*a,2*b+1); addedge(2*a+1,2*b); addedge(2*b,2*a+1); addedge(2*b+1,2*a); } } } if (solvable(2*n)) printf("YES\n"); else printf("NO\n"); return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。