【算法】2-sat问题【模板】
什么是2-sat问题
有n个布尔型变量xi,另外m个需要满足的条件。每个条件都是“xi为真/假或者xj为真/假”。这句话中的“或者”意味着两个条件中至少有一个正确。2-sat问题的目标是给每个变量赋值,使得所有的条件得到满足。
算法的大致过程是这样的:
构造一张有向图G,其中每个变量拆成两个结点2i和2i+1,分别表示xi为假和xi为真。最后要为每个变量选其中一个结点标记。
对于每个“xi为假或者xj为假"这样的条件,我们连两条对称的有向边。我们上面说过,或者意味着两个中间至少有一个正确。所以如果xi为真的话,那么xj一定为假,所以我们从2*i+1向2*j连一条有向边。同样的道理,我们也从2*j+1向2*i连一条有向边。
接下来我们逐一考虑每个没有赋值的变量,设为xi。我们先假定它为假,然后标记结点2i,并且沿着有向边标记所有能标记的结点。如果标记的过程中发现某个变量对应的两个结点都被标记,则xi假这个假定不成立,需要改为xi为真,然后重新标记。
模板代码如下
code from LRJ
/*
将每个变量拆成两个点2i和2i+1,分别表示xi为假和xi和真
对于每个条件,连两条对称的有向边。
逐一考虑没有赋值的变量,先假定它为假,然后标记结点2i,然后沿着有向边标记所有能标记的结点
如果标记的过程中 发现某个变量对应的两个结点都被标记,则xi为假这个假定不成立,需要改xi为真
然后重新标记
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <vector> using namespace std;
const int maxn=+;
struct TwoSAT{
int n;
vector<int>G[*maxn];
bool mark[maxn*];
int S[maxn*],c;
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));
}
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);
} 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;
}
};
int main(){
return ;
}
【算法】2-sat问题【模板】的更多相关文章
- [置顶] 小白学习KM算法详细总结--附上模板题hdu2255
KM算法是基于匈牙利算法求最大或最小权值的完备匹配 关于KM不知道看了多久,每次都不能完全理解,今天花了很久的时间做个总结,归纳以及结合别人的总结给出自己的理解,希望自己以后来看能一目了然,也希望对刚 ...
- KMP算法,匹配字符串模板(返回下标)
//KMP算法,匹配字符串模板 void getNext(int[] next, String t) { int n = next.length; for (int i = 1, j = 0; i & ...
- KMP算法自我理解 和 模板
字符串 abcd abc abcd abc 匹配串 cdabcd 匹配串的 next 0 0 0 0 1 2: 开始匹配 abcd abc abcd abc cd abc d a,d 匹配失 ...
- 【经验】实现STL算法时遇到的模板编译错误问题
在实现set_union算法时调用了自己写的copy算法,出现了以下问题. Error 1 error C2665: 'xyz_stl::__copy' : none of the 2 overloa ...
- Bellman-ford算法、SPFA算法求解最短路模板
Bellman-ford 算法适用于含有负权边的最短路求解,复杂度是O( VE ),其原理是依次对每条边进行松弛操作,重复这个操作E-1次后则一定得到最短路,如果还能继续松弛,则有负环.这是因为最长的 ...
- Dijkstra算法求最短路模板
Dijkstra算法适合求不包含负权路的最短路径,通过点增广.在稠密图中使用优化过的版本速度非常可观.本篇不介绍算法原理.只给出模板,这里给出三种模板,其中最实用的是加上了堆优化的版本 算法原理 or ...
- LCA倍增算法的错误与模板
先上我原来的错误的代码 type node=^link; link=record num:int64; next:node; end; var fa:..,..] of int64; dep:..] ...
- Dijkstra算法(带路径模板)
个人心得:Dijkstra算法是贪心思想的一种延伸,注意路径pre,pre数组表示此时最短路径中的前一个顶点.每次更新到目的点时更新: 从源点出发,更新路径,然后找出此时最短的点,然后以这个点为头,看 ...
- dinic 算法 基本思想及其模板
“网络流博大精深”—sideman语 一个基本的网络流问题 感谢WHD的大力支持 最早知道网络流的内容便是最大流问题,最大流问题很好理解: 解释一定要通俗! 如右图所示,有一个管道系统,节点{1,2, ...
- 算法笔记--BSGS && exBSGS 模板
https://www.cnblogs.com/sdzwyq/p/9900650.html 模板: unordered_map<int, int> mp; LL q_pow(LL n, L ...
随机推荐
- 几个开源ssg 技术方案
1. Nanoc 2. Middle Man App 3. Hexo 4. DocPad 5. Hugo 6. Jekyll 7. Octopress 8. Harp ...
- Automating CSS Regression Testing
The following is a guest post by Garris Shipon . We've touched on the four types of CSS testing here ...
- server 2012系统更改电脑密码
在server2012系统中将鼠标指针移至任务栏右侧,在弹出的操作栏中单击“设置”选项. 在打开的设置操作界面中,鼠标单击“控制面板”选项. 在打开的控制面板选项窗口中,单击“管理工具”选 ...
- bzoj 3994 [SDOI2015]约数个数和——反演
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3994 \( d(i*j)=\sum\limits_{x|i}\sum\limits_{y|j ...
- Android JNI访问Java成员
在 JNI 调用中,不仅仅 Java 可以调用本地方法,本地方法也可以调用 Java 中的方法和成员变量. Java 中的类封装了属性和方法,想要访问 Java 中的属性和方法,首先要获得 Java ...
- 手动封装OpenCV1.0的IplImage读取保存功能遇到的小问题
最近准备重新学习图像处理的知识,主要目的是自己实现一遍图像处理的算法,所以除了读取.保存图像外的操作都自己写,没想到直接封装OpenCV的读取.保存功能的第一步就出错.关键代码如下 void MyIm ...
- Oracle合并某一列
本文转载自:https://www.cnblogs.com/LeiYang5237/p/6761183.html 一.oracle11g使用listagg() within group()函数 如图一 ...
- Android关于inflate的root参数
最近在用View inflate(Context context, int resource, ViewGroup root)方法时,在第三个参数root上碰到了点麻烦. 一般在写ListView的a ...
- 如何在Oracle中向Collection类型的变量中逐条插入数据
这篇文章将要介绍如果需要生成一个新的Collection并且向其中添加数据的方法. procedure insert_object(d in dept_array, d2 out dept_array ...
- Tkinter Dimensions
Tkinter Dimensions: 各种长度,宽度,和其他部件的尺寸可以在许多不同的单位描述 各种长度,宽度,和其他部件的尺寸可以在许多不同的单位描述. 如果您设置了尺寸为整数,它被假定为 ...