POJ 3678 Katu Puzzle
2016-07-15 12:19
323 查看
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.
【题目分析】
其实暴搜加上适当的剪枝可以0ms的,但是熟悉一下2set,建图的方式非常巧妙。
【代码】
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.
【题目分析】
其实暴搜加上适当的剪枝可以0ms的,但是熟悉一下2set,建图的方式非常巧妙。
【代码】
#include <cstdio> #include <vector> using namespace std; typedef long long ll; int dfn[2001],vis[2001],low[2001],sta[2001*10],bel[2001],tem,cnt,top; vector<int>e[2001]; void tarjan(int u) { dfn[u]=low[u]=++tem; vis[u]=true; sta[++top]=u; int v,i,l=e[u].size(); for(i=0;i<l;i++) { v=e[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v]&&dfn[v]<low[u]) low[u]=dfn[v]; } if(dfn[u]==low[u]) { cnt++; do { v=sta[top--]; vis[v]=false; bel[v]=cnt; }while(v!=u); } } bool twoSAT(int n) { for(int i=0;i<2*n;i++) if(!dfn[i]) tarjan(i); for(int i=0;i<n;i++) if(bel[2*i]==bel[2*i+1]) return false; return true; } int main() { int n,m,i,a,b,c; char s[5]; scanf("%d%d",&n,&m); for(i=0;i<m;i++) { scanf("%d%d%d%s",&a,&b,&c,s); if(s[0]=='A') { if(c) e[2*a+1].push_back(2*a),e[2*b+1].push_back(2*b); else e[2*a].push_back(2*b+1),e[2*b].push_back(2*a+1); } else if(s[0]=='O') { if(c) e[2*a+1].push_back(2*b),e[2*b+1].push_back(2*a); else e[2*a].push_back(2*a+1),e[2*b].push_back(2*b+1); } } if(twoSAT(n)) puts("YES"); else puts("NO"); return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2159 Ancient Cipher
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- [数论]poj2635__The Embarrassed Cryptographer
- [二分图匹配]poj2446__Chessboard
- POJ1050 最大子矩阵和
- 用单调栈解决最大连续矩形面积问题