Algorithm Description

\(2-SAT\)问题就是给定一串布尔变量,每个变量只能为真或假。

要求对这些变量进行赋值,满足布尔方程。

会有一些形如 \(x_1||x_2\) 或者 \(x_5||(!x_6)\) 的条件

所谓布尔方程就是赋值之后满足所有的条件

首先扯一句,如果这个条件变成三或者三以上个\(x\)相关的了,就只能\(2^n\)枚举了

(好像是 \(N-SAT\) 问题是 \(NP\) 完全的)

然后我们思考如何求解这样的问题

前人告诉我们,可以把这些变量转移到图上进行操作

\[Begin
\]

首先拆点: \(i->i\) 同时 \((!i)->i+n\)

然后我们我们考虑建图的时候

对于每一个条件: \(a||b\) ,连上 \((!a)->b\) 和 \((!b)->a\) 的两条有向边

这里可以理解成【\(b\) 假则 \(a\) 必须真,\(a\) 假则 \(b\)必须真】

考虑 \(tarjan\) 求一波强连通分量,如果有 \(scc[i]==scc[i+n]\) 直接无解

显然真假是不一样的(就是不能赋相同的值)

\[Finished
\]

如果要跑方案,就直接输出\([scc[i]<scc[i+n]]\) 就好

例题

1.【模板】\(2-SAT\)问题

2.JSOI2010 满汉全席

由于实在是模板题(不知为啥当时放这么一个纯板子……),就不写了

Code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
namespace yspm{
inline int read()
{
int res=0,f=1; char k;
while(!isdigit(k=getchar())) if(k=='-') f=-1;
while(isdigit(k)) res=res*10+k-'0',k=getchar();
return res*f;
}
const int N=4e6+10;
int n,m,a,b,x,y,tim,top,tot,cnt;
int dfn[N],low[N],st[N],vis[N],scc[N],head[N];
struct node{int to,nxt;}e[N];
inline void add(int u,int v){e[++cnt].nxt=head[u],e[cnt].to=v; head[u]=cnt; return ;}
inline void tarjan(int u,int fa)
{
dfn[u]=low[u]=++tim; st[++top]=u; vis[u]=1;
for(int i=head[u];i;i=e[i].nxt)
{
int t=e[i].to; if(t==fa) continue;
if(!dfn[t]) tarjan(t,u),low[u]=min(low[u],low[t]);
else if(vis[t]) low[u]=min(low[u],dfn[t]);
}
if(dfn[u]==low[u])
{
tot++; while(st[top]!=u) scc[st[top]]=tot,vis[st[top--]]=0;
scc[st[top]]=tot; vis[st[top--]]=0;
}
return ;
}
signed main()
{
n=read(); m=read();
for(int i=1;i<=m;++i)
{
a=read(); x=read(); b=read(); y=read();
if(!x&&!y) add(a+n,b),add(b+n,a);
if(!x&&y) add(a+n,b+n),add(b,a);
if(x&&!y) add(a,b),add(b+n,a+n);
if(x&&y) add(a,b+n),add(b,a+n);
}
for(int i=1;i<=2*n;++i) if(!dfn[i]) tarjan(i,0);
for(int i=1;i<=n;++i)
{
if(scc[i]==scc[i+n]) return puts("IMPOSSIBLE"),0;
}
puts("POSSIBLE"); for(int i=1;i<=n;++i) printf(scc[i]>scc[i+n]?"1 ":"0 ");
return 0;
}
}
signed main(){return yspm::main();}

瞎看吧,这个 \(add\) 压行有点严重了,没去格式化 \(2333\)

最新文章

  1. 协议分析 - DHCP协议解码详解
  2. python 获取脚本所在目录
  3. Java使用poi操作cexel
  4. ngrok内网穿透利器在windws下的使用
  5. Android Logcat 封装类
  6. IGS_学习笔记08_IREP通过soapUI测试客户化Web Service调用(案例)
  7. 将EXE作为资源,然后在释放到磁盘上并运行该exe程序(使用了FindResource,LoadResource,然后用CFile写成一个文件)
  8. PHP QR CODE生成二维码
  9. c++,C# 转换
  10. NOI2007 货币兑换
  11. 屏蔽手势UIGestureRecognizer 先后响应
  12. C#打印条码BarTender SDK打印之路和离开之路(web平凡之路)
  13. bootstrap 响应式布局 居中问题
  14. 运维必备:Oracle自备份精简教程(linux及win)
  15. 运算符优先级--C
  16. Failed to find configured root that contains
  17. hibernate--博客
  18. c# 转换成时间类型
  19. java设计模式-----12、外观模式
  20. 安装VisualSVN Server 报&quot;Service &#39;VisualSVN Server&#39; failed to start. Please check VisualSVN Server log in Event Viewer for more details&quot;错误.原因是启动&quot;VisualSVN Server&quot;失败

热门文章

  1. C++ STD Gems04
  2. Upgrade to 17.1 from 17.0 problem:UnicodeEncodeError: &#39;ascii&#39; codec can&#39;t encode character &#39;\xc4&#39; in position 50: ordinal not in range(128)
  3. Day 1:线程与进程系列问题(一)
  4. XML--XSL
  5. android手机客户端测试-思考方向
  6. Maven:Failed to read artifact descriptor for xxx
  7. Mac Github:第一次上传成功,解决图片不可显示,Initial commit Untracked files
  8. bootstrap快速上手
  9. java.io.tmpdir在哪里?
  10. Java学习十八