poj--3678--Katu Puzzle(2-sat 建模)
Time Limit: 1000MS | Memory Limit: 65536KB | 64bit IO Format: %I64d & %I64u |
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:
XaopXb = 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<stdio.h> #include<string.h> #include<queue> #include<stack> #include<vector> #include<algorithm> using namespace std; #define MAX 1000000+10 int low[MAX],dfn[MAX]; int sccno[MAX],m,n; int scc_cnt,dfs_clock; bool Instack[MAX]; vector<int>G[MAX]; stack<int>s; void init() { for(int i=0;i<2*n;i++) G[i].clear(); } void getmap() { while(m--) { int a,b,c; char op[5]; memset(op,'\0',sizeof(op)); scanf("%d%d%d%s",&a,&b,&c,op); if(op[0]=='A') { if(c==1) { G[a+n].push_back(a); G[b+n].push_back(b); } else { G[a].push_back(b+n); G[b].push_back(a+n); } } else if(op[0]=='O') { if(c==1) { G[a+n].push_back(b); G[b+n].push_back(a); } else { G[a].push_back(a+n); G[b].push_back(b+n); } } else if(op[0]=='X') { if(c==1) { G[a+n].push_back(b); G[b+n].push_back(a); G[a].push_back(b+n); G[b].push_back(a+n); } else { G[a].push_back(b); G[b].push_back(a); G[a+n].push_back(b+n); G[b+n].push_back(a+n); } } } } void tarjan(int u,int fa) { int v; low[u]=dfn[u]=++dfs_clock; Instack[u]=true; s.push(u); for(int i=0;i<G[u].size();i++) { v=G[u][i]; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[v],low[u]); } else if(Instack[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { ++scc_cnt; for(;;) { v=s.top(); s.pop(); Instack[v]=false; sccno[v]=scc_cnt; if(v==u) break; } } } void find(int l,int r) { memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(sccno,0,sizeof(sccno)); memset(Instack,false,sizeof(Instack)); scc_cnt=dfs_clock=0; for(int i=l;i<=r;i++) if(!dfn[i]) tarjan(i,-1); } void solve() { for(int i=0;i<n;i++) { if(sccno[i]==sccno[i+n]) { printf("NO\n"); return ; } } printf("YES\n"); } int main() { while(scanf("%d%d",&n,&m)!=EOF) { init(); getmap(); find(0,2*n-1); solve(); } return 0; }