2-SAT问题总结

2-SAT问题:n个布尔型的变量,给出m个约束条件,约束条件例如:A,B不能同时为真,A,B必须同时为真等。

看了算法入门经典中的解决办法,关于这种解决办法比较容易理解,并且效率也不错。构造一张有向图G,其中n个变量拆成n*2个变量,也就是xi用xi*2和xi*2+1表示,如果前者标记为1,那么说明xi为真,如果后者标记为1,那么说明xi为假。对于约束条件就可进行构成边,例如xi为假或者xj为假,也就是xi为假xj必须为真,xj为假xi必须为真,这样就得到两条有向边,xi*2+1 -> xj*2    xj*2+1 -> xi*2,这样就得到了有向图G。

有向图中所有的有向边肯定组成了若干连通分量,某一连通分量中的,一点如果为1那么,这个连通分量中的所有点都要是1,反之也是,如果某一点既为1,又为0,那么m个约束条件肯定是产生矛盾了,那么这个问题就无法解决。

模拟这个过程的时候用的是dfs,从一点开始我们先假设这个点为0,然后从这个点开始遍历所有它能到达的点,都标记一下,如果标记过程中发现某点已经为1了,那么就以这个点为1再以这个点开始遍历,如果这个点为1为0都会产生矛盾,那么就是出现了上面的问题,约束条件产生矛盾,问题无法得到解决。

/*********************************************2-SAT模板*********************************************/
const int maxn=+;
struct TwoSAT
{
int n;//原始图的节点数(未翻倍)
vector<int> G[maxn*];//G[i].j表示如果mark[i]=true,那么mark[j]也要=true
bool mark[maxn*];//标记
int S[maxn*],c;//S和c用来记录一次dfs遍历的所有节点编号 //从x执行dfs遍历,途径的所有点都标记
//如果不能标记,那么返回false
bool dfs(int x)
{
if(mark[x^]) return false;//这两句的位置不能调换
if(mark[x]) return true;
mark[x]=true;
S[c++]=x;
for(int i=;i<G[x].size();i++)
if(!dfs(G[x][i])) return false;
return true;
} void init(int n)
{
this->n=n;
for(int i=;i<*n;i++)
G[i].clear();
memset(mark,,sizeof(mark));
} //加入(x,xval)或(y,yval)条件
//xval=0表示假,yval=1表示真
void add_clause(int x,int xval,int y,int yval)//这个地方不是一尘不变的,而是参照问题的约束条件进行加边
{
x=x*+xval;
y=y*+yval;
G[x^].push_back(y);
G[y^].push_back(x);
} //判断当前2-SAT问题是否有解
bool solve()
{
for(int i=;i<*n;i+=)
if(!mark[i] && !mark[i+])
{
c=;
if(!dfs(i))
{
while(c>) mark[S[--c]]=false;
if(!dfs(i+)) return false;
}
}
return true;
}
};
/*********************************************2-SAT模板*********************************************/

2-SAT问题总结的更多相关文章

  1. 多边形碰撞 -- SAT方法

    检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...

  2. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

  3. Map Labeler POJ - 2296(2 - sat 具体关系建边)

    题意: 给出n个点  让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...

  4. 学习笔记(two sat)

    关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...

  5. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  6. HIT 1917 2—SAT

    题目大意:一国有n个党派,每个党派在议会中都有2个代表, 现要组建和平委员会,要从每个党派在议会的代表中选出1人,一共n人组成和平委员会. 已知有一些代表之间存在仇恨,也就是说他们不能同时被选为和平委 ...

  7. 2 - sat 模板(自用)

    2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一  POJ 3207 Ikki's Story IV ...

  8. SAT考试里最难的数学题? · 三只猫的温暖

    问题 今天无意中在Quora上看到有人贴出来一道号称是SAT里最难的一道数学题,一下子勾起了我的兴趣.于是拿起笔来写写画画,花了差不多十五分钟搞定.觉得有点意思,决定把解题过程记下来.原帖的图太小,我 ...

  9. 世界碰撞算法原理和总结(sat gjk)

    序言 此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法.如有其它见解,可以跟作者商讨.(杨子剑,zijian_yang@yeah.net). 在一个世界中,有多个物体,物体可以 ...

  10. hdu 4115 (2—SAT)

    题意:两个人石头剪刀布,一个人的出法已确定,另一个人的出法有一定约束,某两次要相同或者不同,问你第二个人能否全部都不失败. 思路:根据Bob出的情况,我们可以确定每次Alice有两种方案. R与P,S ...

随机推荐

  1. Java开发中遇到的问题

    head丢失 html的dtd不对 Integer数据类型 使用==比较 这个肯定错(事后才知道) sql语句处理分组的时候,在本地服务使用没问题,在服务器上出现sql异常 group by语句规范, ...

  2. sessionStorage、localStorage 存储及如何存储数组与对象

    1.存储,获取,清楚 sessionStorage.setItem("key",val) sessionStorage.getItem("key") sessi ...

  3. [js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,复古,蒙版,透明)

    接着上文[js高手之路] html5 canvas系列教程 - 状态详解(save与restore),相信大家都应该玩过美颜功能,而我们今天要讲的就是canvas强大的像素处理能力,通过像素处理,实现 ...

  4. HDFS概述(1)————HDFS架构

    概述 Hadoop分布式文件系统(HDFS)是一种分布式文件系统,用于在普通商用硬件上运行.它与现有的分布式文件系统有许多相似之处.然而,与其他分布式文件系统的区别很大.HDFS具有高度的容错能力,旨 ...

  5. apollo实现c#与android消息推送(一)

    之前做了c#推送消息到手机端,限于网络要求,不能使用百度等现成的推送,查了许多资料,七拼八凑终于凑齐,记录下来,即是复习也是希望对来者有所帮助. 我开发的环境是windows,使用java开发的Apa ...

  6. K相邻算法

    刚开始学习机器学习,先跟这<机器学习实战>学一些基本的算法 ----------------------------------分割线--------------------------- ...

  7. hadoop(一)之初识大数据与Hadoop

    前言 从今天起,我将一步一步的分享大数据相关的知识,其实很多程序员感觉大数据很难学,其实并不是你想象的这样,只要自己想学,还有什么难得呢? 学习Hadoop有一个8020原则,80%都是在不断的配置配 ...

  8. JAVA提高一:静态导入、可变参数、增强型for循环、装拆箱

    国庆假期已结束,假期8天,全部在家带娃,体会到了妻子的不容易,需要好好努力来多赚钱了,言归正传.10月份开始进去JAVA 高级语法知识学习,本节复习学习的为:静态导入.可变参数.增强型for循环.装拆 ...

  9. selenium 调用键盘按键

    1.想要调用键盘按键操作需要引入keys包: from selenium.webdriver.common.keys import keys 通过send_keys() 调用按键 send_keys( ...

  10. C#一款比较美观的验证码

    using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System. ...