poj3678 Katu Puzzle 【解法一】
2016-08-04 13:40
197 查看
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: AND 0 1 0 0 0 1 0 1 OR 0 1 0 0 1 1 1 1
XOR 0 1 0 0 1 1 1 0
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”.
解法二见【这里】。
2-SAT模板题。
把每个点拆成选和不选,然后用每个条件相互连边。
比如a&b=0就是a=1->b=0,b=1->a=0,也就是说连边表示由起点这个状态能推导出终点的状态。
比较特殊的是a&b=1和a|b=0,这就不是推导关系了,而是已经确定的元素。这里需要特殊判断一下。
然后在图上进行dfs,直到所有点都被标记为止。需要注意的是不需要回溯,也就是如果某一个点无论取1还是0都失败了,那就不用再回去更改之前的值,直接宣告失败即可。
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: AND 0 1 0 0 0 1 0 1 OR 0 1 0 0 1 1 1 1
XOR 0 1 0 0 1 1 1 0
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”.
解法二见【这里】。
2-SAT模板题。
把每个点拆成选和不选,然后用每个条件相互连边。
比如a&b=0就是a=1->b=0,b=1->a=0,也就是说连边表示由起点这个状态能推导出终点的状态。
比较特殊的是a&b=1和a|b=0,这就不是推导关系了,而是已经确定的元素。这里需要特殊判断一下。
然后在图上进行dfs,直到所有点都被标记为止。需要注意的是不需要回溯,也就是如果某一个点无论取1还是0都失败了,那就不用再回去更改之前的值,直接宣告失败即可。
#include<cstdio> #include<cstring> #include<vector> #include<stack> using namespace std; vector<int> to[2010]; stack<int> sta; int m,n; bool b[2010],vis,must[2010]; void init() { int i,j,k,x,y,z; char s[5]; scanf("%d%d",&n,&m); for (i=1;i<=m;i++) { scanf("%d%d%d%s",&x,&y,&z,s+1); if (s[1]=='A') { if (z==1) must[2*x]=must[2*y]=1; else { to[2*x].push_back(2*y+1); to[2*y].push_back(2*x+1); } } if (s[1]=='O') { if (z==0) must[2*x+1]=must[2*y+1]=1; else { to[2*x+1].push_back(2*y); to[2*y+1].push_back(2*x); } } if (s[1]=='X') { if (z==1) { to[2*x].push_back(2*y+1); to[2*x+1].push_back(2*y); to[2*y].push_back(2*x+1); to[2*y+1].push_back(2*x); } else { to[2*x+1].push_back(2*y+1); to[2*x].push_back(2*y); to[2*y+1].push_back(2*x+1); to[2*y].push_back(2*x); } } } } bool dfs(int x) { if (b[x^1]||must[x^1]) return 0; if (b[x]) return 1; b[x]=1; sta.push(x); for (int i=0;i<to[x].size();i++) if (!dfs(to[x][i])) return 0; return 1; } bool solve() { int i,j,k,x,y,z; for (i=0;i<n;i++) { if (!must[i*2+1]&&dfs(i*2)) continue; while (!sta.empty()) { b[sta.top()]=0; sta.pop(); } if (must[i*2]||!dfs(i*2+1)) return 0; } return 1; } int main() { init(); if (solve()) printf("YES\n"); else printf("NO\n"); }
相关文章推荐
- poj3678 Katu Puzzle 【解法二】
- POJ3678_Katu Puzzle_2-sat
- poj3678-Katu Puzzle
- POJ3678:Katu Puzzle 2-SAT
- [POJ3678]Katu Puzzle(2-SAT)
- POJ3678 Katu Puzzle 【2-sat】
- poj3678 Katu Puzzle
- poj3678 Katu Puzzle 2011-12-26
- POJ3678 Katu Puzzle
- Poj3678:Katu Puzzle
- [POJ3678]Katu Puzzle(2-SAT)
- Poj3678:Katu Puzzle
- 【2-SAT】POJ3678-Katu Puzzle
- POJ3678 Katu Puzzle【2-SAT】
- POJ3678 Katu Puzzle(2-sat tanjar判矛盾)
- poj3678 Katu Puzzle(2-SAT+经典建图)
- [POJ3678] Katu Puzzle
- POJ 3678 Katu Puzzle
- POJ-3678 Katu Puzzle 2sat
- POJ.3678.Katu Puzzle(2-SAT)