2-SAT详解
来源:互联网 发布:java属性是什么意思 编辑:程序博客网 时间:2024/06/06 12:37
以下内容摘自《算法竞赛入门经典训练指南》:
2-SAT问题是这样的:有n个布尔变量xi,另有m个需要满足的条件,每个条件的形式都是“xi为真/假或者xj为真/假“
2-SAT的解法有多种不同的叙述方式,这里采用一种比较容易理解的,且效率也不错的方式。构造一张有向图,其中每个变量xi拆分成两个结点2i和2i + 1,分别表示xi为假和xi为真,最后要为每个变量选其中的一个结点进行标记,比如标记了2i,表示xi为假,标记了2i + 1表示xi为真了
对于“xi为假或者xj为假“这种条件,就连一条有向边,2i + 1->2j,表示如果标记了xi为真,那么xj就必须要为假,同理,还得另外一条有向边2j + 1-> 2i,表明如果xj为真了,xi必须为假,这样才能满足上述的条件
接下来考虑一下每个没有赋值的变量,设为xi。先假设他为假,然后标记结点2i,接着沿着有向边标记所有能标记的点,如果标记过程中发现某个变量对应的两个结点都被标记,则“xi为假“这个假设是不成立的,需要改成“xi为真“,然后重新标记。注意,这个算法没有回溯过程,如果当前考虑的变量不管赋值为真还是为假都会引起矛盾的话,那就可以证明整个2-SAT问题无解(即使调整以前赋值的其他变量也没用)
算法模版:
#include <cstdio>#include <cstring>#include <vector>using namespace std;const int MAXNODE = 5010 * 2;struct TwoSat{ int n, top; vector<int> G[MAXNODE]; bool mark[MAXNODE]; int Stack[MAXNODE]; void init(int n) { this->n = n; for (int i = 0; i < 2 * n; i++) G[i].clear(); memset(mark, 0, sizeof(mark)); } //x = xval或者y = yval,这个表示或的关系 void AddClause(int x, int xval, int y, int yval) { x = x * 2 + xval; y = y * 2 + yval; G[x ^ 1].push_back(y); G[y ^ 1].push_back(x); } //x = xval的时候,y必须等于yval,这个表示且的关系 void AddLimit(int x, int xval, int y, int yval) { x = x * 2 + xval; y = y * 2 + yval; G[x].push_back(y); } bool dfs(int u) { //当前需要标记的结点是u,如果u ^ 1这个结点已经被标记过了,就表示两个结点都要被标记掉,明显冲突了 if (mark[u ^ 1]) return false; if (mark[u]) return true; mark[u] = true; //模拟栈 Stack[++top] = u; //和u相邻的点都进行标记,以判断是否出错 for (int i = 0; i < G[u].size(); i++) if (!dfs(G[u][i])) return false; return true; } bool solve() { for (int i = 0; i < 2 * n; i += 2) //如果在其他点的标志过程中,其中一个点被标记了,就无需在枚举了,因为在dfs的过程中,和其相连的点也被标记了,较少了重复枚举 if (!mark[i] && !mark[i ^ 1]) { top = 0; //假设xi为假是错误的,这时候就要进行回溯,将dfs过程中标记过的点还原,再判断对错 if (!dfs(i)) { while (top) mark[Stack[top--]] = false; if (!dfs(i ^ 1)) return false; } } return true; }}Two;int main() { return 0;}
习题的话,可以在本博客找,我有进行分类的
0 0
- 2-SAT详解
- 图论2-SAT算法详解
- 2-sat
- 【2-SAT】
- 2-SAT
- 2 - sat
- 2-SAT
- 2-SAT
- 2-Sat
- 2-SAT
- 2-sat
- 2-sat
- 2-SAT
- 2-Sat
- 2-SAT
- 2-SAT
- 2-SAT
- 2-SAT
- 航空电子全双工交换式以太网AFDX
- HDU 1028 整数分化
- Unknown column 'Mary' in 'field list'
- SGU 134 树形DP
- SiteMesh 过滤不装饰的页面
- 2-SAT详解
- UML-类图、包图、对象图
- HDU 5514 容斥原理
- poj 1064 二分 Cable master
- 创业漫话九(公司的组织形式 )
- 【浅墨Unity3D Shader编程】之九 深入理解Unity5中的Standard Shader (一)&屏幕水幕特效的实现
- 第9周项目3-稀疏矩阵的三元组表示的实现及应用(2)
- jQuery第四课 ——运动
- 上传文件消失问题