2020/4/26 2-sat 学习笔记
2-sat 吧。。。。
其实我jio得它一点都不难
嗯
2-sat是个啥东西呢?
其实就是有很多人,他们每个人有两个要求,一个要求可以说是要求一个数为0或1
而对于第i个数,我们可以选择为0或为1
最终询问是否可以满足全部人的要求
(我讲了个啥啊)
emmmm
其实我一看就大概懂了。。。
这不就是约束的变形吗。。。
之间建图判断个连通性就好了啊。。。
这不是模板题吗。。。
其实确实很简单。。。
(还不如说是我上了一节tarjan课 )(逃)
其实吧。。。
这个还真的是(省选)T1的难度。。。awa
主要是以为这个很好就可以看出来是这种问题。。。
进入正题。
对于这种问题,建图是显而易见的吧。
既然2-sat问题能够被单独列出来,肯定也是有原因的。
2sat其实妙就妙在他的建图上。
对于一个人,我们如果要满足他的条件a,b如果我们不满足a,那么就一定要满足b如果我们不满足b,那么就一定要满足a
于是我们就把这个问题从“或者”,转化为了“一定”
而这就是一个很明显的约束条件了。
即为边(a,!b)和(b,!a);
这其实就是如果不满足b时就一定要满足a
如果不满足a时就一定要满足b
然后,图就建好了
是不是很好理解?(其实我老师讲的时候我觉得很好,为什么我讲就不一样了啊淦)
这里给一份建图的代码。
n=read();m=read();
for(int i=1;i<=m;i++)
{
a=read();va=read();
b=read();vb=read();
if(va&&vb)
{
add(a,b+n);
add(b,a+n);
}
else
if(!va&&vb)
{
add(a+n,b+n);
add(b,a);
}
else
if(va&&!vb)
{
add(b+n,a+n);
add(a,b);
}
else
if(!va&&!vb)
{
add(b+n,a);
add(a+n,b);
}
}
简单易懂
awa
这个其实就是整个2-sat最精髓的部分了。
剩下的就是tarjan
对于我们建的图,选择的点一定不能同时有一个点以及他的负点。
一旦选择了,就什么这个情况是无解的。
tarjan判断是否在同一个强联通分量里就好了。
但是如果题目要求字典序,就是另一个故事了。
那么只能暴力。
虽然说吧。。。
暴力的时间复杂度也是很优秀的了吧。。。
可是它能被卡掉。
一个链就炸了。
这里我放上全部的代码,是tarjan的
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int head[4000001],tot,n,m,a,b,va,vb,dfsc,ccs,color[2000001],dfn[2000001],low[2000001];bool vis[2000001];
stack<int> stk;
struct edge
{
int next,to;
}e[4000001];
inline ll read()
{
char c=getchar();ll a=0,b=1;
for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;
return a*b;
}
void add(int i,int j)
{
e[++tot].next=head[i];
e[tot].to=j;
head[i]=tot;
}
void tarjan(int x,int fa)
{
dfn[x]=low[x]=++dfsc;
stk.push(x);vis[x]=true;
for(int i=head[x];i!=0;i=e[i].next)
{
int u=e[i].to;
if(u==fa)continue;
if(!dfn[u])
{
tarjan(u,x);
low[x]=min(low[x],low[u]);
}
else
if(vis[u])//有一条返祖边,要更新
{
low[x]=min(low[x],dfn[u]);
}
}
if(dfn[x]==low[x])//有一个强联通分量
{
++ccs;
do
{
color[x]=ccs;
x=stk.top();stk.pop();vis[x]=false;
}
while(dfn[x]!=low[x]);
}
}
int main()
{
freopen("2sat.in","r",stdin);
freopen("2sat.out","w",stdout);
n=read();m=read();
for(int i=1;i<=m;i++)
{
a=read();va=read();
b=read();vb=read();
if(va&&vb)
{
add(a,b+n);
add(b,a+n);
}
else
if(!va&&vb)
{
add(a+n,b+n);
add(b,a);
}
else
if(va&&!vb)
{
add(b+n,a+n);
add(a,b);
}
else
if(!va&&!vb)
{
add(b+n,a);
add(a+n,b);
}
}
for(int i=1;i<=n*2;i++)
{
if(dfn[i]==0)
{
tarjan(i,0);
}
}
for(int i=1;i<=n;i++)
{
if(color[i]==color[i+n])
{
puts("IMPOSSIBLE");
return 0;
}
}
puts("POSSIBLE");
for(int i=1;i<=n;i++)
{
cout<< (color[i]>color[i+n]) <<' ';
}
return 0;
}

2020/4/26 2-sat 学习笔记的更多相关文章
- 2020年Yann Lecun深度学习笔记(下)
2020年Yann Lecun深度学习笔记(下)
- 2020年Yann Lecun深度学习笔记(上)
2020年Yann Lecun深度学习笔记(上)
- 2020年度钻石C++C学习笔记(2)--《博学谷》
2020年度钻石C++C--<博学谷> 1.以下标示符中命名合法的是A A.__A__ B.ab.c C.@rp D.2Y_ 2.设 a 和 b 均为 double 型变量,且a=5.5. ...
- 2020年度钻石C++C学习笔记(1)《博学谷》
1.C语言概述 1.1 什么是C语言 一提到语言这个词语,自然会想到的是像英语.汉语等这样的自然语言,因为它是人和人交换信息不可缺少的工具. 而今天计算机遍布了我们生活的每一个角落,除了人和人的相互交 ...
- 2020年度钻石C++C学习笔记(3)--《博学谷》
1.Unix/Linux操作系统介绍 1.1 操作系统的作用 1.1.1 操作系统的目标 l 方便:使计算机系统易于使用 l 有效:以更有效的方式使用计算机系统资源 l 扩展:方便用户有效开发.测试和 ...
- 学习笔记之C / C++
面试总结之C/C++ - 浩然119 - 博客园 https://www.cnblogs.com/pegasus923/p/5558919.html 学习笔记之C++ How to Program(p ...
- Linux命令学习笔记目录
Linux命令学习笔记目录 最近正在使用,linux,顺便将用到的命令整理了一下. 一. 文件目录操作命令: 0.linux命令学习笔记(0):man 命令 1.linux命令学习笔记(1):ls命令 ...
- Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor
Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...
- [原创]java WEB学习笔记26:MVC案例完整实践(part 7)---修改的设计和实现
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Flutter学习笔记(26)--返回拦截WillPopScope,实现1秒内点击两次返回按钮退出程序
如需转载,请注明出处:Flutter学习笔记(26)--返回拦截WillPopScope,实现1秒内点击两次返回按钮退出程序 在实际开发中,为了防止用户误触返回按钮导致程序退出,通常会设置为在1秒内连 ...
随机推荐
- 用R语言实现并行计算:基于R的数据处理和分析工具
目录 引言 随着数据量的爆炸式增长,数据处理和分析的需求也越来越大.传统的批处理计算已经无法满足高效的数据处理和分析需求,因此,并行计算成为了一个重要的技术方向.然而,R语言作为一种开源.可视化能力强 ...
- 有哪些ASIC加速技术可以实现低功耗运行?
目录 文章主题: 10. 有哪些ASIC加速技术可以实现低功耗运行? 背景介绍:随着移动设备.物联网.云计算等应用场景的不断增长,功耗成为了一个日益重要的技术问题.为了在移动设备上实现更长时间的运行, ...
- 区块链应用:椭圆曲线数字签名算法ECDSA
1 椭圆曲线密码学 椭圆曲线密码学(Elliptic Curve Cryptography,缩写ECC),是基于椭圆曲线数学理论实现的一种非对称加密算法.椭圆曲线在密码学中的使用是在1985年有Nea ...
- Java 访问控制权限修饰符
1.访问控制权限修饰符来控制元素的访问范围 2.访问控制权限修饰符包括: public 表示公开的,任何位置都可以可以访问 protected 同包,子类 缺省 同包 private 表示私有的,只能 ...
- Oracle sql 错误 : ORA-01861: 文字与格式字符串不匹配和日期与字符串互转问题解决
正确的要这样的: public int update(String ceratedate); <update id="update" parameterType=" ...
- linux内核笔记(二)微机计算机组成结构
一个系统有四个基本组成部分: 输入部分:接收系统的数据(键盘等) 处理中心:处理(cpu) 能源部分:处理需要的硬件资源(内存等) 输出部分:显示给用户(显示器等) 计算机系统分为: 计算机系统分为软 ...
- zabbix 主动模式下报文分析
获取监控项列表 客户端发起请求 3次握手之后,请求监控项列表: {"request":"active checks","host":&quo ...
- 层叠样式表(CSS)1
一.css的简介 1.层叠样式表的含义 层叠样式表:css是不仅是表现HTML的语言.还是进行样式修饰的语言 层叠:是对一个元素多次设置同一个样式,层层叠加覆盖,如不同的样式对一html标签进行修饰, ...
- python:时间模块dateutil
安装 pip install python-dateutil dateutil模块主要有两个函数,parser和rrule. 其中parser是根据字符串解析成datetime,而rrule则是根据定 ...
- 时序数据库 InfluxDB 第一篇 安装部署
使用场景: 最近项目上遇到大数据存储的问题,一个IOT融合项目,涉及到大量的工控监测数据存储.当前存储到关系库中的数据已经达到2亿条了.做了很多优化,查询还是很慢.便想着是否有更好的解决方案. 了解到 ...