Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6994 | Accepted: 2563 |
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
#include <iostream>
#include <cstdio>
#include <string>
#include <stack>
#include <string.h>
using namespace std;
#define MAXN 3000000 + 10
#define MAXV 1000 + 10
int n, m;
struct Edge
{
int v, next;
}edge[MAXN];
int head[2 * MAXV], e, ind, cnt;
int dfn[2 * MAXV], low[2 * MAXV], belong[2 * MAXV];
bool ins[2 * MAXV];
void add(int u, int v)
{
edge[e].v = v;
edge[e].next = head[u];
head[u] = e++;
}
void init()
{
e = ind = cnt = 0;
memset(head, -1, sizeof(head));
}
int sta[2 * MAXV], top = 0;
stack <int> s;
void tarjan(int u)
{
dfn[u] = low[u] = ++ind;
ins[u] = true;
s.push(u);
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].v;
if (!dfn[v]) //errir!
{
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (ins[v])
{
low[u] = min(low[u], dfn[v]);
}
}
if (low[u] == dfn[u])
{
int x;
do
{
x = s.top();
s.pop();
ins[x] = false;
belong[x] = cnt;
}while (x != u);
cnt++;
}
}
void solve()
{
for (int i = 0; i < 2 * n; i++)
{
if (!dfn[i])
{
tarjan(i);
}
}
bool flag = true;
for (int i = 0; i < n; i++)
{
if (belong[i] == belong[i + n])
{
flag = false;
break;
}
}
if (flag)
{
printf("YES\n");
}
else
{
printf("NO\n");
}
}
void input()
{
int a, b, c;
char str[10];
scanf("%d %d", &n, &m);
init();
for (int i = 0; i < m; i++)
{
scanf("%d %d %d %s", &a, &b, &c, str);
if (str[0] == 'A')
{
if (c == 0)
{
add(a + n, b);
add(b + n, a);
}
else
{
add(a, a + n);
add(b, b + n);
add(a + n, b + n);
add(b + n, a + n);
}
}
else if (str[0] == 'O')
{
if (c == 0)
{
add(a + n, a);
add(b + n, b);
add(a, b);
add(b, a);
}
else
{
add(a, b + n);
add(b, a + n);
}
}
else
{
if (c == 0)
{
add(a, b);
add(b, a);
add(a + n, b + n);
add(b + n, a + n);
}
else
{
add(a, b + n);
add(b + n, a);
add(a + n, b);
add(b, a + n);
}
}
}
solve();
}
int main()
{
input();
return 0;
}