poj3678 Katu Puzzle
Posted zbtrs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3678 Katu Puzzle相关的知识,希望对你有一定的参考价值。
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 10239 | Accepted: 3823 |
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) such that for each edge e(a, b) labeled by op and c, the following formula holds:
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
Source
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <stack> using namespace std; const int maxn = 1010 * 3,maxm = 2000010; int n,m,head[maxn],top,to[maxm],nextt[maxm],tot = 1,dfs_clock,pre[maxn],low[maxn],scc[maxn]; stack <int> s; void add(int x,int y) { to[tot] = y; nextt[tot] = head[x]; head[x] = tot++; } void tarjan(int u) { pre[u] = low[u] = ++dfs_clock; s.push(u); for (int i = head[u];i; i = nextt[i]) { int v = to[i]; if (!pre[v]) { tarjan(v); low[u] = min(low[u],low[v]); } else if (!scc[v]) low[u] = min(low[u],pre[v]); } if (pre[u] == low[u]) { top++; while (1) { int t = s.top(); s.pop(); scc[t] = top; if (t == u) break; } } } int main() { scanf("%d%d",&n,&m); for (int i = 1; i <= m; i++) { int a,b,c; char op[5]; scanf("%d%d%d",&a,&b,&c); scanf("%s",op); if (op[0] == ‘A‘) //and { if (c == 1) { add(a + n,b + n); add(b + n,a + n); add(a,a + n); //a如果为0显然不能满足要求,所以a必须为1,所以从0连向1 add(b,b + n); } else { add(a + n,b); add(b + n,a); } } if (op[0] == ‘X‘) { if (c == 1) { add(a,b + n); add(a + n,b); add(b, a + n); add(b + n,a); } else { add(a,b); add(b,a); add(a + n,b + n); add(b + n,a + n); } } if (op[0] == ‘O‘) { if (c == 1) { add(a,b + n); add(b,a + n); } else { add(a,b); add(b,a); add(a + n,a); //a,b必须全都为0才可以,选1后我们强行让它选0. add(b + n,b); } } } for (int i = 0; i <= 2 * n - 1; i++) if (!pre[i]) tarjan(i); for (int i = 0; i < n; i++) if (scc[i] == scc[i + n]) { printf("NO\n"); return 0; } printf("YES\n"); return 0; }
以上是关于poj3678 Katu Puzzle的主要内容,如果未能解决你的问题,请参考以下文章