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秒内连 ...
随机推荐
- XTTS系列之三:中转空间的选择和优化
通常选择XTTS做迁移的数据库都不会太小的,至少都是几T.几十T这样的规模,这种级别的数据量原有空间不够用,所以在迁移过程临时用作存放迁移数据库备份文件的空间也是需要提前考虑规划的问题. 最近就有客户 ...
- 简约版八股文(day1)
Java基础 面向对象的三大基本特征 封装:将一些数据和对这些数据的操作封装在一起,形成一个独立的实体.隐藏内部的操作细节,并向外提供一些接口,来暴露对象的功能. 继承:继承是指子类继承父类,子类获得 ...
- 我用numpy实现了VIT,手写vision transformer, 可在树莓派上运行,在hugging face上训练模型保存参数成numpy格式,纯numpy实现
先复制一点知乎上的内容 按照上面的流程图,一个ViT block可以分为以下几个步骤 (1) patch embedding:例如输入图片大小为224x224,将图片分为固定大小的patch,patc ...
- 基于SM4和LSB算法实现图片数字水印加密软件(密码赛)
一.前言 密码赛和星火杯时做的小项目,密码赛的时候是个半成品,没有过初赛,星火杯之前完善了 设计思路 最开始是想做一个图片水印用作对图片来源的不可否认性做保护,又考虑保护数据完整性,因此选中了易损水印 ...
- PE结构总览
pe文件经历了从16位系统到32位系统的过度.因此32系统下的每一个PE文件都可以在16位系统下运行. 16位系统下的PE结构 在16位系统下,PE结构可以大致分为两个部分:DOS头和一些其他数据 # ...
- MAUI Blazor 加载本地图片的解决方案
前言 为了解决MAUI Blazor无法加载本地图片,https://github.com/dotnet/maui/issues/2907,所以写了这篇文章. 有token大佬珠玉在前,https:/ ...
- ansible 的特点
ansible的特点 基于Python语言实现 模块化,调用特定的模块,完成特定任务 部署简单,基于python和SSH(默认已安装),yum install 即可,不需要客户端 安全,基于OpenS ...
- .net通用RSA加密工具类
目前最流行的加密算法莫过于RSA了,以下是我们.net/.net core C#生成环境用的RSA加密工具类,在此分享给大家. using System; using System.IO; using ...
- 【技术积累】Linux中的命令行【理论篇】【一】
7z命令 命令介绍 7z命令是Linux系统中的一个压缩和解压缩工具,它可以用来创建.压缩和解压缩7z格式的文件.7z是一种高压缩率的文件格式,通常比其他常见的压缩格式(如zip和gzip)具有更高的 ...
- mysql创建可以让Django链接的用户名
输入以下命令: 1 grant all privileges on 库名.* to 账户名@'%' identified by 'password'; 2 flush privileges;