2-SET详解
前置知识
SET问题的标准定义:在计算机科学中,布尔可满足性问题(有时称为命题可满足性问题,缩写为SATISFIABILITY或SAT)是确定是否存在满足给定布尔公式的解释的问题。(全是废话)
说人话就是,你要给n个变量,n需要给他赋值使它满足给你一些形如(x1为1或x3为0或x4为3)的条件,你必须满足所有条件(满足例子的条件需要x1为1,x3为0,x4为3中至少有一个成立)。
但这个问题并不好解决,一旦变量的取值范围变大时间复杂度将不可估量。所以我们考虑最简单的2-sat问题(1-sat大家都会)
2-SAT思路
1.因为2-sat只有两种取值所以一个变量分为x1和x2两个代表取第一种值和第二种值(以下用0,1代表)
2.对于每一个条件如(x1为1或x2为0)可以引申出两个条件若x1为0则x2一定为0,若x2为1则x1为1,我们将x1为0向x2为0以及x2为1向x1为1连边。
3.将所有条件按上面的方法处理后,做强联通分量,如果同一个变量的两个取值在一个强联通分量则意味从变量的0可以推到1,从1可以推到0,则取任何值都不满足条件。如果不在则可以确定变量取值为拓扑序大的数,因为从取值1推到取值2,取值2推不倒取值1,则选择取值2满足条件。
上图条件(x1为1或x2为0)(x1为0或x3为0)(x1为0或x3为0)
答案为x1为0,x2为0,x3为0(答案不唯一),绿色为一种可能的拓扑序,由绿色的拓扑序可推出上面的答案
例题
P4782 【模板】2-SAT - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
AC代码
- #include <bits/stdc++.h>
- using namespace std;
- const int N=2e6+10;
- int n,m,cnt,ys,nxt[2*N],hd[2*N],go[2*N],tot,dfn[2*N],low[2*N],col[2*N],ans[N],top,sta[2*N],vis[2*N];
- void add(int x,int y)
- {
- nxt[++tot]=hd[x];go[tot]=y;hd[x]=tot;
- return ;
- }
- void tarjan(int u)
- {
- dfn[u]=low[u]=++cnt;
- sta[++top]=u;
- vis[u]=1;
- for(int i=hd[u];i;i=nxt[i])
- {
- int v=go[i];
- if(!dfn[v])
- {
- tarjan(v);
- low[u]=min(low[u],low[v]);
- }
- else if(vis[v]) low[u]=min(low[u],dfn[v]);
- }
- if(dfn[u]==low[u])
- {
- ys++;
- while(sta[top]!=u)
- {
- col[sta[top]]=ys;
- vis[sta[top]]=0;
- top--;
- }
- col[sta[top]]=ys;
- vis[sta[top]]=0;
- top--;
- }
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=1;i<=m;i++)
- {
- int a,az,b,bz;scanf("%d%d%d%d",&a,&az,&b,&bz);
- add(a+(az&1)*n,b+(bz^1)*n);//1到n为第i个变量选1,n+1到n+n为第i-n个变量选0
- add(b+(bz&1)*n,a+(az^1)*n);//简单的建图法,不懂的自己分情况验证
- }
- for(int i=1;i<=2*n;i++)
- if(!dfn[i])tarjan(i);
- for(int i=1;i<=n;i++)
- {
- if(col[i]==col[i+n])//在同一强联通分量中
- {
- printf("IMPOSSIBLE\n");
- return 0;
- }
- }
- printf("POSSIBLE\n");
- for(int i=1;i<=n;i++)
- {
- if(col[i]>col[i+n])printf("0 ");//tarjan的是倒序,所以选小的
- else printf("1 ");
- }
- return 0;
- }
P4171 [JSOI2010] 满汉全席 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
几乎是模板题,改输入就行了。
- #include <bits/stdc++.h>
- using namespace std;
- const int N=2e6+10;
- int k,n,m,cnt,ys,nxt[2*N],hd[2*N],go[2*N],tot,dfn[2*N],low[2*N],col[2*N],top,sta[2*N],vis[2*N];
- void add(int x,int y)
- {
- nxt[++tot]=hd[x];go[tot]=y;hd[x]=tot;
- return ;
- }
- void tarjan(int u)
- {
- dfn[u]=low[u]=++cnt;
- sta[++top]=u;
- vis[u]=1;
- for(int i=hd[u];i;i=nxt[i])
- {
- int v=go[i];
- if(!dfn[v])
- {
- tarjan(v);
- low[u]=min(low[u],low[v]);
- }
- else if(vis[v]) low[u]=min(low[u],dfn[v]);
- }
- if(dfn[u]==low[u])
- {
- ys++;
- while(sta[top]!=u)
- {
- col[sta[top]]=ys;
- vis[sta[top]]=0;
- top--;
- }
- col[sta[top]]=ys;
- vis[sta[top]]=0;
- top--;
- }
- }
- int main()
- {
- scanf("%d",&k);
- while(k--)
- {
- memset(hd,0,sizeof(hd));
- memset(dfn,0,sizeof(dfn));
- ys=tot=cnt=0;
- scanf("%d%d",&n,&m);
- for(int i=1;i<=m;i++)
- {
- char aa[5],bb[5];
- int a=0,b=0,az,bz;
- scanf("%s%s",aa,bb);
- int c=1;
- while(aa[c]>='0'&&aa[c]<='9')
- a=a*10+aa[c]-'0',c++;
- c=1;
- while(bb[c]>='0'&&bb[c]<='9')
- b=b*10+bb[c]-'0',c++;
- if(aa[0]=='m')az=0;
- else az=1;
- if(bb[0]=='m')bz=0;
- else bz=1;
- add(a+(az&1)*n,b+(bz^1)*n);
- add(b+(bz&1)*n,a+(az^1)*n);
- }
- for(int i=1;i<=2*n;i++)
- if(!dfn[i])tarjan(i);
- int flag=1;
- for(int i=1;i<=n;i++)
- {
- if(col[i]==col[i+n])
- {
- flag=0;
- printf("BAD\n");
- break;
- }
- }
- if(flag)printf("GOOD\n");
- }
- return 0;
- }
2-SET详解的更多相关文章
- Linq之旅:Linq入门详解(Linq to Objects)
示例代码下载:Linq之旅:Linq入门详解(Linq to Objects) 本博文详细介绍 .NET 3.5 中引入的重要功能:Language Integrated Query(LINQ,语言集 ...
- 架构设计:远程调用服务架构设计及zookeeper技术详解(下篇)
一.下篇开头的废话 终于开写下篇了,这也是我写远程调用框架的第三篇文章,前两篇都被博客园作为[编辑推荐]的文章,很兴奋哦,嘿嘿~~~~,本人是个很臭美的人,一定得要截图为证: 今天是2014年的第一天 ...
- EntityFramework Core 1.1 Add、Attach、Update、Remove方法如何高效使用详解
前言 我比较喜欢安静,大概和我喜欢研究和琢磨技术原因相关吧,刚好到了元旦节,这几天可以好好学习下EF Core,同时在项目当中用到EF Core,借此机会给予比较深入的理解,这里我们只讲解和EF 6. ...
- Java 字符串格式化详解
Java 字符串格式化详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 文中如有纰漏,欢迎大家留言指出. 在 Java 的 String 类中,可以使用 format() 方法 ...
- Android Notification 详解(一)——基本操作
Android Notification 详解(一)--基本操作 版权声明:本文为博主原创文章,未经博主允许不得转载. 微博:厉圣杰 源码:AndroidDemo/Notification 文中如有纰 ...
- Android Notification 详解——基本操作
Android Notification 详解 版权声明:本文为博主原创文章,未经博主允许不得转载. 前几天项目中有用到 Android 通知相关的内容,索性把 Android Notificatio ...
- Git初探--笔记整理和Git命令详解
几个重要的概念 首先先明确几个概念: WorkPlace : 工作区 Index: 暂存区 Repository: 本地仓库/版本库 Remote: 远程仓库 当在Remote(如Github)上面c ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- Node.js npm 详解
一.npm简介 安装npm请阅读我之前的文章Hello Node中npm安装那一部分,不过只介绍了linux平台,如果是其它平台,有前辈写了更加详细的介绍. npm的全称:Node Package M ...
- .NET应用和AEAI CAS集成详解
1 概述 数通畅联某综合SOA集成项目的统一身份认证工作,需要第三方系统配合进行单点登录的配置改造,在项目中有需要进行单点登录配置的.NET应用系统,本文专门记录.NET应用和AEAI CAS的集成过 ...
随机推荐
- Java Collection接口下的“ List 集合” 与 “ Set 集合 ”
Java Collection接口下的" List 集合" 与 " Set 集合 " 每博一文案 一个人最好的底牌,就这两个字: 靠谱,是最高级的聪明. 师父说 ...
- JAVA也能用上Seq啦
前言 在.NET生态中,Serilog凭借其强大的结构化日志记录功能和与Seq的无缝集成,已经成为许多开发者的首选日志记录工具.Seq作为一个日志检索和仪表板工具,能够将日志中的插值转换为结构化数据, ...
- hexo 博客插入本地图片时遇到的坑
哈喽大家好,我是咸鱼. 最近一直在折腾博客的事,说是 hexo 极易上手,我觉得只仅限于在安装部署的时候,随着对 hexo 的深入使用,发现遇到的问题还是挺多的. 那今天来讲一下我在把本地图片插入到 ...
- Java工具类库大总结
1. Java自带工具方法 1.1 List集合拼接成以逗号分隔的字符串 // 如何把list集合拼接成以逗号分隔的字符串 a,b,c List<String> list = Arrays ...
- 2020年9月至10月 Splashtop 新功能
Splashtop 已为 Splashtop Business Access.Splashtop Remote Support.Splashtop SOS 和 Splashtop On-Prem ...
- 网络安全—模拟IP代理隐藏身份
文章目录 网络拓扑 安装 使用 代理服务器设置 隐藏者设置 使用古老的ccproxy实现代理服务器,仅做实验用途,禁止做违法犯罪的事情,后果自负. 网络拓扑 均使用Windows Server 200 ...
- C语言:约瑟夫问题——使用循环链表解决
传说有30个乘客同乘一条船,因为严重超载,加上风浪水作,危险万分.船长告诉乘客,只有将全船一半的乘客投入海 中,其余人才能幸免于难.他们约定了一个规则:30个人围成一圈,由第一个人数起,依次报数,数到 ...
- Python 将PowerPoint (PPT/PPTX) 转为HTML
PPT是传递信息.进行汇报和推广产品的重要工具.然而,有时我们需要将这些精心设计的PPT演示文稿发布到网络上,以便于更广泛的访问和分享.本文将介绍如何使用Python将PowerPoint文档转换为网 ...
- MyBatis抛出BindingException异常可能是你忘了配置资源拷贝
最近博主在搭建Mybatis项目时遇到了一问题,在一切配置妥当后,开始运行测试代码,但是此时控制台无情的抛出了异常: 开始寻找问题根源 咦?难道是我哪里写错,我的第一反应是我的xml配置文件哪里写错了 ...
- MySQL中drop/truncate/delete的区别
1.Delete语句执行删除的过程是每次从表中删除一行,并且同时将删除操作作为事务记录在日志中保存以便进行进行回滚操作(只删除表数据). delete是DML,执行delete操作时,每次从表中删除一 ...