POJ 3678 2-SAT
来源:互联网 发布:此情唯有落花知txt 编辑:程序博客网 时间:2024/04/28 23:46
因为A和B的取值只有0,1,在运算里就可以用2-SAT来解决。
建图过程如下:
1) X AND Y=1,Add(I',J'),Add(J',I'),Add(I,I'),Add(J,J')
2) X AND Y=0,Add(I',J),Add(J',I)
3) X OR Y=1,Add(I,J'),Add(J,I')
4) X OR Y=0,Add(I,J),Add(J,I),Add(I',I),Add(J',J)
5) X XOR Y=1,Add(I',J),Add(J',I),Add(I,J'),Add(J,I')
6) X XOR Y=0,Add(I',J'),Add(J',I'),Add(I,J),Add(J,I)
一开始我没理解红色部分的建图。后来我才知道,如果没有红色部分,那么有一部分的冲突就没有解决。比如:样例里同时有A OR B = 0, A OR B = 1。如果没有下面两句话,Add(I',I),Add(J',J),那么程序是判断不出冲突的,因为在建图的时候就只有A<->B,A -> B', B -> A'。A和A’,B和B‘并不在一个强连通分量里,所以无法判别冲突,画个图看一下就知道了。
对于红色部分更好的解释应该是:X OR Y的时候,X或Y任何一个不能为1,否则就会有冲突,因此从X'和Y'向X, Y连接一条边。
Code:
#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>using namespace std;const int maxn = 2222;const int maxm = 2222222;struct node{ int v, next;}edge[maxm];int head[maxn], k, n, m;int low[maxn], dfn[maxn], belong[maxn], inde, cnt;int stack[maxn << 2], top;bool instack[maxn];void add_edge(int u, int v){ edge[k].v = v, edge[k].next = head[u]; head[u] = k ++;}void tarjan(int u){ int v; dfn[u] = low[u] = inde ++; instack[u] = true; stack[top ++] = u; for(int i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); } else if(instack[v]) low[u] = min(low[u], dfn[v]); } if(low[u] == dfn[u]) { cnt ++; do{ v = stack[-- top]; instack[v] = false; belong[v] = cnt; num[cnt] ++; }while(v != u); }}int main(){ while(~scanf("%d%d", &n, &m)) { memset(head, -1, sizeof(head)); k = 0; while(m --) { int u, v, val; char op[10]; scanf("%d%d%d%s", &u, &v, &val, op); if(op[0] == 'A') { if(val == 0) { add_edge(u + n, v); add_edge(v + n, u); } else { add_edge(u + n, v + n); add_edge(v + n, u + n); add_edge(u, u + n); // u can't be 0 add_edge(v, v + n); // v can't be 0 } } else if(op[0] == 'O') { if(val == 0) { add_edge(u, v); add_edge(v, u); add_edge(u + n, u); // u can't be 1 add_edge(v + n, v); // v can't be 1 } else { add_edge(u, v + n); add_edge(v, u + n); } } else if(op[0] == 'X') { if(val == 0) { add_edge(u, v); add_edge(v, u); add_edge(u + n, v + n); add_edge(v + n, u + n); } else { add_edge(u, v + n); add_edge(v, u + n); add_edge(v + n, u); add_edge(u + n, v); } } } memset(dfn, 0, sizeof(dfn)); memset(instack, false, sizeof(instack)); top = 0, cnt = 0, inde = 1; int nn = 2 * n; for(int i = 0; i < nn; i ++) if(!dfn[i]) tarjan(i); bool ok = true; for(int i = 0; i < nn; i ++) if(belong[i] == belong[i + n]) ok = false; if(!ok) printf("NO\n"); else printf("YES\n"); }}
- 2-sat POJ 3678
- 【2-SAT】POJ 3678
- POJ 3678 2-sat
- POJ 3678 2-SAT
- POJ 3678 2-sat
- poj 3678 2-sat
- poj 3678 2-sat
- POJ 3678 2-sat裸题
- POJ-3678(2-SAT)
- poj-3678(2-SAT)
- POJ 3678 2SAT总结
- POJ 3678 2-sat模板
- POJ 3678 OO版2-SAT模板
- poj 3678(2-sat入门)
- POJ 3678 2-SAT 第一题
- POJ 3678 Katu Puzzle (2-SAT)
- POJ 3678 Katu Puzzle(2-SAT判断)
- POJ 3678 Kath Puzzle (2-sat)
- 高性能数据中心网络的流量收敛设计
- Mac OS X下配置Cocos2d-x for Android(Eclipse)&IOS(Xcode)开发环境
- 侠客行
- 集中不同环境下--正则表达式--区别
- atoi原型
- POJ 3678 2-SAT
- 苹果Mac OS X下配置Cocos2d-x for Android(Eclipse)和IOS(Xcode)开发【内有cocos2dx2.0.3版本的配置】
- UVA 12291 Polyomino Composer
- MVC模式(简单模拟QQ登录界面)
- 常用Photoshop CS6快捷键
- TopK
- Linix 启动过程详解
- 阿姆斯特朗数
- NOIP 2005 等价表达式 四则运算