Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 5833 | Accepted: 2110 |
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
根据运算规则连好该连的点,点0到n-1表示对应点的值取0,n到2n-1表示对应点的值取1
所以点i到i+n相连则矛盾
然后tarjan算法求出个点的col值
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <string>
#define MAXN 5100
using namespace std;
///Tarjan//
vector< int > point[5010]; //point[i][j]是与编号为i的点相连的第j个点的编号
bool mat[5100][5100];
bool vis[5100];
int low[5100];
int dfn[5100];
int col[5100];
int sta[5100];
int cnt;
int n,m , r;
int Bcnt;
int top;
void init(){
for(int i = 0;i < n * 2; i ++){
point[i].clear();
}
memset(low, 0, sizeof(low));
memset(dfn, 0, sizeof(dfn));
memset(col, 0, sizeof(col));
memset(vis, false, sizeof(vis));
Bcnt = 0;
top = 0;
cnt = 0;
}
void dfs(int x){ //递归,tarjan
vis[x] = true;
sta[++top] = x;
cnt ++;
low[x] = cnt;
dfn[x] = cnt;
int len = point[x].size();
for(int i = 0; i < len; i ++){
int tmp = point[x][i];
if(!dfn[tmp]){
dfs(tmp);
low[x] = min(low[x], low[tmp]);
}
else if(vis[tmp] && dfn[tmp] < low[x])
low[x] = dfn[tmp];
}
int v;
if(low[x] == dfn[x]){
Bcnt ++;
do{
v = sta[top --];
vis[v] = false;
col[v] = Bcnt;
}while(x != v );
}
}
//
int main(){
int i,j,k,x,y,a,b,c;
char op[8];
while(~scanf("%d %d",&n,&m)){
init();
for (i=0;i<m;i++){
scanf("%d %d %d %s",&a,&b,&c,op);
if (op[0]=='A'){
if (c==1){
point[a].push_back(a + n);
point[b].push_back(b + n);
point[a + n].push_back(b + n);
point[b + n].push_back(a + n);
}
else{
point[a + n].push_back(b);
point[b + n].push_back(a);
}
}
if (op[0]=='O'){
if (c==1){
point[a].push_back(b + n);
point[b].push_back(a + n);
}
else{
point[a + n].push_back(a);
point[b + n].push_back(b);
point[a].push_back(b);
point[b].push_back(a);
}
}
if (op[0]=='X'){
if (c==1){
point[a].push_back(b + n);
point[b].push_back(a + n);
point[a + n].push_back(b);
point[b + n].push_back(a);
}
else{
point[a].push_back(b);
point[b].push_back(a);
point[a + n].push_back(b + n);
point[b + n].push_back(a + n);
}
}
}
for(i = 0; i < 2 * n; i ++){
if(!dfn[i]){
dfs(i);
}
}
int ans=1;
for (i=0;i<n;i++){
if (col[i]==col[i+n])
ans = 0;
}
if (ans==1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}