POJ 3678 Katu Puzzle(2-SAT)
来源:互联网 发布:淘宝可以用什么支付 编辑:程序博客网 时间:2024/04/30 19:08
POJ 3678 Katu Puzzle(2-SAT)
http://poj.org/problem?id=3678
题意:
一个N个顶点和M条边的有向图,每个顶点能取0或1两个值.现在每条边被一个操作符(or,and,xor)以及一个值(0或1)标记了,表示a与b按操作符运算的结果是值(0或1).问你该有向图是否有可行解?
分析:
由于每个点只能取0或1两个值,所以我们把该问题转化为2-SAT问题.原图中的每个点对应2-SAT中的每个点.对于每种运算有下列转换方式:
a and b = 0 转换为 a=0 或 b=0
a and b = 1 转换为 a=1 且 b=1 即添加边 2*a->2*a+1 2*b->2*b+1(只要a为0或b为0必然引起矛盾)
a or b = 0 转换为 2*a+1->2*a 2*b+1->2*b(只要a为1或b为1必然引起矛盾)
a or b = 1 转换为 a=1 或b=1
a xorb=0转换为 a=1且b=1 或 a=0且b=0 即连下面的边:
2*a->2*b 2*b->2*a 2*a+1->2*b+1 2*b+1->2*a+1.
a xor b=1 转换为a=1且b=0 或a=0且b=1 则连下面的边:
2*a+1->2*b 2*b->2*a+1 2*a->2*b+1 2*b+1->2*a
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;const int maxn=1000+10;struct TwoSAT{ int n; vector<int> G[maxn*2]; int S[maxn*2],c; bool mark[maxn*2]; bool dfs(int x) { if(mark[x^1]) return false; if(mark[x]) return true; mark[x]=true; S[c++]=x; for(int i=0;i<G[x].size();i++) if(!dfs(G[x][i])) return false; return true; } void init(int n) { this->n=n; for(int i=0;i<n*2;i++) G[i].clear(); memset(mark,0,sizeof(mark)); } void add_clause(int x,int xval,int y,int yval)//这里的函数做了修改,只加单向边 { x=x*2+xval; y=y*2+yval; G[x].push_back(y); } bool solve() { for(int i=0;i<2*n;i+=2) if(!mark[i] && !mark[i+1]) { c=0; if(!dfs(i)) { while(c>0) mark[S[--c]]=false; if(!dfs(i+1)) return false; } } return true; }}TS;int main(){ int n,m; scanf("%d%d",&n,&m); TS.init(n); int a,b,c; char op[10]; for(int i=0;i<m;i++) { scanf("%d%d%d%s",&a,&b,&c,op); if(op[0]=='A') { if(c==0) { TS.add_clause(a,1,b,0); TS.add_clause(b,1,a,0); } else if(c==1) { TS.add_clause(a,0,a,1); TS.add_clause(b,0,b,1); } } else if(op[0]=='O') { if(c==0) { TS.add_clause(a,1,a,0); TS.add_clause(b,1,b,0); } else if(c==1) { TS.add_clause(a,0,b,1); TS.add_clause(b,0,a,1); } } else if(op[0]=='X') { if(c==0) { TS.add_clause(a,0,b,0); TS.add_clause(a,1,b,1); TS.add_clause(b,0,a,0); TS.add_clause(b,1,a,1); } else if(c==1) { TS.add_clause(a,0,b,1); TS.add_clause(a,1,b,0); TS.add_clause(b,0,a,1); TS.add_clause(b,1,a,0); } } } if(TS.solve()) printf("YES\n"); else printf("NO\n"); return 0;}
0 0
- POJ 3678 Katu Puzzle (2-SAT)
- POJ 3678 Katu Puzzle(2-SAT判断)
- poj 3678 Katu Puzzle 2-SAT
- 2-sat->poj 3678 Katu Puzzle
- poj 3678 Katu Puzzle (2-sat)
- POJ 3678 Katu Puzzle(2-SAT)
- poj 3678 2-SAT (Katu Puzzle)
- 【POJ】3678 Katu Puzzle 2-sat
- [2-SAT] poj 3678 Katu Puzzle
- POJ 3678 Katu Puzzle(2-sat)
- POJ 3678 Katu Puzzle(2-sat)
- POJ 3678 Katu Puzzle (2-SAT)
- poj 3678 Katu Puzzle 2-sat
- POJ 3678 - Katu Puzzle(2-SAT)
- POJ 3678 Katu Puzzle 2-SAT
- poj 3678 Katu Puzzle 2-SAT
- POJ 3678 Katu Puzzle(2-SAT)
- Katu Puzzle (poj 3678 2-SAT)
- hdu3033 I love sneakers! (背包问题变形 每种至少买一个)
- Unbuntu下编译ITK,VTK
- 使用yum安装mysql
- extjs4.2.1与三大框架集成
- STAF学习笔记-A
- POJ 3678 Katu Puzzle(2-SAT)
- android 手机一直进安全模式 解决方法
- Git历险记(三)
- 黑马程序员_网络编程
- Java:重写equals()和hashCode()
- 为什么是Createthread后要CloseHandle
- VBA清除Excel密码保护,2003/2007/2010均适用
- C\C++小知识:C\C++中#define和inline的区别
- Path Sum--路径和(重)