学习笔记(two sat)
关于two sat算法
两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf)。
一些题目的题解
关于具体算法
- 首先此算法只对于存在类似于一个点选了另一个点就不能选这样的条件,并且每个点只有两种状态(一般是选或不选),不然是个NP问题
- 大体做法就是先转换模型,把每个点拆成两个,一个代表取,一个代表不取,(注意:图中边代(u->v)代表取u就一定要取v)
- 至于判断是否有可行解只要Tarjan缩点,如果一个点中两个状态的点在同一联通块中则无解,否则一定有可行解。
连边方法
- A,B不能同时取:A->B' B->A‘
- A,B必须反着取:A->B' A'->B B->A' B'->A
- A,B不能都不取:A'->B B'->A
- A,B必须同时取或不取:A->B B->A A'->B' B'->A'
- 必须取A:A'->A
可行方案
Tarjan缩点判无解之后,重新反向建图,开个数组,将A与A‘所在联通块互相标记为敌人,tope DP的时候,依次将点取出,如果其没有颜色,则将其标记为true,同时将其的敌人标记为false即可
poj3207
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
#define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
const int N=1000+5;
bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
template<typename T>T read()
{
T ans=0,f=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
return ans*f;
}
template<typename T>void write(T x,char y)
{
if(x==0)
{
putchar('0');
return;
}
if(x<0)
{
putchar('-');
x=-x;
}
static char wr[20];
int top=0;
for(;x;x/=10)wr[++top]=x%10+'0';
while(top)putchar(wr[top--]);
putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("3207.in","r",stdin);
freopen("3207.out","w",stdout);
#endif
}
int n,m;
struct edge
{
int v,nex;
}e[N*N];
int head[N<<1],tt;
void add(int x,int y)
{
++tt;e[tt].v=y;e[tt].nex=head[x];head[x]=tt;
}
int lef[N],rig[N];
bool check(int i,int j)
{
bool t1,t2;
t1=(lef[i]<=lef[j]&&lef[j]<=rig[i]);
t2=(lef[i]<=rig[j]&&rig[j]<=rig[i]);
return t1^t2;
}
void build(int x)
{
For(i,1,x-1)
{
if(check(i,x))
{
//cout<<i<<' '<<x<<endl;
add(i,x+m);add(x,i+m);
add(i+m,x);add(x+m,i);
}
}
}
void input()
{
n=read<int>();m=read<int>();
For(i,1,m)
{
lef[i]=read<int>()+1;
rig[i]=read<int>()+1;
if(lef[i]>rig[i])swap(lef[i],rig[i]);
build(i);
}
}
int low[N],dfn[N],dfs_clock;
int scc[N],id;
int l[N];
void Tarjan(int u)
{
low[u]=dfn[u]=++dfs_clock;
l[++l[0]]=u;
int v;
for(register int i=head[u];i;i=e[i].nex)
{
v=e[i].v;
if(!dfn[v])
{
Tarjan(v);
cmin(low[u],low[v]);
}
else if(!scc[v])
{
cmin(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
++id;
int k;
do
{
k=l[l[0]--];
scc[k]=id;
}while(k^u);
}
}
void work()
{
For(i,1,m<<1)if(!dfn[i])Tarjan(i);
/*For(i,1,m)
{
printf("%d %d\n",scc[i],scc[i+m]);
}*/
For(i,1,m)
{
if(scc[i]==scc[i+m])
{
puts("the evil panda is lying again");
return;
}
}
puts("panda is telling the truth...");
}
int main()
{
file();
input();
work();
return 0;
}
poj3678
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
#define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
const int N=1e4+5,M=1e6+5;
bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
template<typename T>T read()
{
T ans=0,f=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
return ans*f;
}
template<typename T>void write(T x,char y)
{
if(x==0)
{
putchar('0');
return;
}
if(x<0)
{
putchar('-');
x=-x;
}
static char wr[20];
int top=0;
for(;x;x/=10)wr[++top]=x%10+'0';
while(top)putchar(wr[top--]);
putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("3678.in","r",stdin);
freopen("3678.out","w",stdout);
#endif
}
struct edge
{
int v,nex;
}e[M<<2];
int head[N<<1],tt;
int n,m;
void add(int x,int y)
{
++tt;e[tt].v=y;e[tt].nex=head[x];head[x]=tt;
}
void input()
{
int a,b,c;
char opt[10];
n=read<int>();m=read<int>();
For(i,1,m)
{
a=read<int>()+1;b=read<int>()+1;c=read<int>();
scanf("%s",opt);
if(opt[0]=='A')
{
if(c)add(a+n,a),add(b+n,b),add(a,b),add(b,a);
else if(!c)add(a,b+n),add(b,a+n);
}
else if(opt[0]=='O')
{
if(c)add(a+n,b),add(b+n,a);
else if(!c)add(a,a+n),add(b,b+n);
}
else if(opt[0]=='X')
{
if(c)add(a,b+n),add(a+n,b),add(b,a+n),add(b+n,a);
else if(!c)add(a,b),add(b,a),add(a+n,b+n),add(b+n,a+n);
}
}
}
int dfn[N<<1],low[N<<1],l[N<<1],dfs_clock,scc[N<<1],id;
void Tarjan(int u)
{
low[u]=dfn[u]=++dfs_clock;l[++l[0]]=u;
int v;
for(register int i=head[u];i;i=e[i].nex)
{
v=e[i].v;
if(!dfn[v])
{
Tarjan(v);
cmin(low[u],low[v]);
}
else if(!scc[v])
{
cmin(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
int k;
id++;
do
{
k=l[l[0]--];
scc[k]=id;
}while(k^u);
}
}
void work()
{
For(i,1,n)if(!dfn[i])Tarjan(i);
For(i,1,n)
{
if(scc[i]==scc[i+n]){puts("NO");return;}
}
puts("YES");
}
int main()
{
file();
input();
work();
return 0;
}
poj3683
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
#define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
const int N=5e3+5;
bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
template<typename T>T read()
{
T ans=0,f=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
return ans*f;
}
template<typename T>void write(T x,char y)
{
if(x==0)
{
putchar('0');putchar('0');putchar(y);
return;
}
if(x<0)
{
putchar('-');
x=-x;
}
if(x<10)putchar('0');
static char wr[20];
int top=0;
for(;x;x/=10)wr[++top]=x%10+'0';
while(top)putchar(wr[top--]);
putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("3683.in","r",stdin);
freopen("3683.out","w",stdout);
#endif
}
struct edge
{
int u,v,nex;
}e[N*N];
int head[N<<1],tt;
int n;
void add(int x,int y)
{
++tt;e[tt].u=x;e[tt].v=y;e[tt].nex=head[x];head[x]=tt;
}
int st[N][5],ed[N][5],las[N];
void deal(int i)
{
st[i][4]+=las[i];
st[i][3]+=st[i][4]/60;
st[i][4]%=60;
ed[i][2]-=las[i];
while(ed[i][2]<0)
{
ed[i][2]+=60;
ed[i][1]-=1;
}
}
bool early(int t1,int t2,int t3,int t4,bool flag)
{
if(t1<t3)return 1;
if(t1==t3&&t2<t4)return 1;
if(flag&&t1==t3&&t2==t4)return 1;
return 0;
}
void build()
{
For(i,1,n)For(x,1,n)
{
if(i==x)continue;
if(early(st[i][1],st[i][2],st[x][1],st[x][2],1))
if(early(st[x][1],st[x][2],st[i][3],st[i][4],0))
add(i,x+n),add(x,i+n);
if(early(ed[i][1],ed[i][2],st[x][1],st[x][2],1))
if(early(st[x][1],st[x][2],ed[i][3],ed[i][4],0))
add(i+n,x+n),add(x,i);
if(early(ed[i][1],ed[i][2],ed[x][1],ed[x][2],1))
if(early(ed[x][1],ed[x][2],ed[i][3],ed[i][4],0))
add(i+n,x),add(x+n,i);
if(early(st[i][1],st[i][2],ed[x][1],ed[x][2],1))
if(early(ed[x][1],ed[x][2],st[i][3],st[i][4],0))
add(i,x),add(x+n,i+n);
}
}
void input()
{
n=read<int>();
For(i,1,n)
{
st[i][1]=st[i][3]=read<int>();st[i][2]=st[i][4]=read<int>();
ed[i][1]=ed[i][3]=read<int>();ed[i][2]=ed[i][4]=read<int>();
las[i]=read<int>();
deal(i);
}
}
int dfn[N<<1],low[N<<1],l[N<<1],dfs_clock,scc[N<<1],id;
void Tarjan(int u)
{
low[u]=dfn[u]=++dfs_clock;l[++l[0]]=u;
int v;
for(register int i=head[u];i;i=e[i].nex)
{
v=e[i].v;
if(!dfn[v])
{
Tarjan(v);
cmin(low[u],low[v]);
}
else if(!scc[v])
{
cmin(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
int k;
id++;
do
{
k=l[l[0]--];
scc[k]=id;
}while(k^u);
}
}
int beg[N<<1],nex[N<<1],to[N<<1],E,cf[N<<1],in[N<<1];
void add_new(int x,int y)
{
++E;to[E]=y;nex[E]=beg[x];beg[x]=E;
}
void rebuild()
{
int u,v;
For(i,1,tt)
{
u=scc[e[i].u];v=scc[e[i].v];
if(u^v)
{
add_new(v,u);in[u]++;
}
}
For(i,1,n)
{
cf[scc[i]]=scc[i+n];
cf[scc[i+n]]=scc[i];
}
}
queue<int>q;
int cl[N<<1];
void topesort()
{
int u;
For(i,1,n<<1)if(!in[i])q.push(i);
while(!q.empty())
{
u=q.front();q.pop();
if(cl[u]==0)cl[u]=1,cl[cf[u]]=-1;
for(register int i=beg[u];i;i=nex[i])
{
if(!--in[to[i]])q.push(to[i]);
}
}
}
void out()
{
For(i,1,n)
{
if(cl[scc[i]]==1)
{
write(st[i][1],':');write(st[i][2],' ');
write(st[i][3],':');write(st[i][4],'\n');
}
else if(cl[scc[i+n]]==1)
{
write(ed[i][1],':');write(ed[i][2],' ');
write(ed[i][3],':');write(ed[i][4],'\n');
}
}
}
void work()
{
For(i,1,n<<1)if(!dfn[i])Tarjan(i);
For(i,1,n)
{
if(scc[i]==scc[i+n]){puts("NO");return;}
}
puts("YES");
rebuild();
topesort();
out();
}
int main()
{
file();
input();
build();
work();
return 0;
}
POJ2723
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
#define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
const int N=2e3+5;
bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
template<typename T>T read()
{
T ans=0,f=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
return ans*f;
}
template<typename T>void write(T x,char y)
{
if(x==0)
{
putchar('0');putchar(y);
return;
}
if(x<0)
{
putchar('-');
x=-x;
}
static char wr[20];
int top=0;
for(;x;x/=10)wr[++top]=x%10+'0';
while(top)putchar(wr[top--]);
putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
freopen("2723.in","r",stdin);
freopen("2723.out","w",stdout);
#endif
}
struct edge
{
int v,nex;
}e[N*N];
int head[N<<1],tt;
int n,m;
int key[N];
void add(int x,int y)
{
++tt;e[tt].v=y;e[tt].nex=head[x];head[x]=tt;
}
int a[N],b[N];
void input()
{
int x,y;
For(i,0,n-1)
{
x=read<int>();y=read<int>();
key[x]=i<<1;key[y]=key[x]|1;
}
For(i,1,m)
{
a[i]=read<int>();b[i]=read<int>();
}
}
int dfn[N<<1],low[N<<1],scc[N<<1],id,dfs_clock;
int l[N<<1];
void build(int mid)
{
int x,y;
tt=0;dfs_clock=id=0;
memset(head,-1,sizeof head);
memset(dfn,0,sizeof dfn);
memset(low,0,sizeof low);
memset(scc,0,sizeof scc);
For(i,1,mid)
{
x=a[i];y=b[i];
if(x==y)add(key[x]^1,key[x]);
else
{
add(key[x]^1,key[y]);
add(key[y]^1,key[x]);
}
}
}
void Tarjan(int u)
{
low[u]=dfn[u]=++dfs_clock;
l[++l[0]]=u;
int v;
for(register int i=head[u];i!=-1;i=e[i].nex)
{
v=e[i].v;
if(!dfn[v])
{
Tarjan(v);
cmin(low[u],low[v]);
}
else if(!scc[v])cmin(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
int k;
++id;
do
{
k=l[l[0]--];
scc[k]=id;
}while(k^u);
}
}
bool check(int mid)
{
build(mid);
For(i,1,n<<1)if(!dfn[i])Tarjan(i);
for(int i=0;i<=n*2-1;i+=2)
{
if(scc[i]==scc[i^1])return 0;
}
return 1;
}
void work()
{
int ans=0,l=1,r=m,mid;
while(l<=r)
{
mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
write(ans,'\n');
}
int main()
{
file();
while(scanf("%d%d",&n,&m))
{
if(n<=0&&m<=0)break;
input();
work();
}
return 0;
}
学习笔记(two sat)的更多相关文章
- <老友记>学习笔记
这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...
- OGG学习笔记02-单向复制配置实例
OGG学习笔记02-单向复制配置实例 实验环境: 源端:192.168.1.30,Oracle 10.2.0.5 单实例 目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1. ...
- python数据分析入门学习笔记
学习利用python进行数据分析的笔记&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据分 ...
- 【MarkMark学习笔记学习笔记】javascript/js 学习笔记
1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...
- Linux 学习笔记之超详细基础linux命令 Part 13
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 12---------------- ...
- Linux 学习笔记之超详细基础linux命令 Part 8
Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 7----------------- ...
- Deep learning with Python 学习笔记(5)
本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...
- 【Redis】命令学习笔记——字符串(String)(23个超全字典版)
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...
- programming-languages学习笔记--第3部分
programming-languages学习笔记–第3部分 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src ...
- 学习笔记 - 2sat
学习笔记 - 2sat 决定重新启用Markdown--只是因为它支持MathJax数学公式 noip考完,既轻松又无奈,回来慢慢填坑 这篇博客也是拖了好久,通过kuangbin的博客才弄懂2-sat ...
随机推荐
- 微信小程序开发 [01] 小程序基本结构和官方IDE简介
1.小程序账户注册 实际上在进行开发时没有注册小程序账户也是可以的,官方提供的IDE提供实时编译模拟预览,和当前你有没有绑定小程序账户没有关系. 当然,最终你要正式上线你的小程序的话,肯定还是需要账户 ...
- 20155218 Exp1 PC平台逆向破解(5)M
20155218 Exp1 PC平台逆向破解(5)M 1. 掌握NOP.JNE.JE.JMP.CMP汇编指令的机器码 NOP:NOP指令即"空指令".执行到NOP指令时,CPU什么 ...
- 20155339平措卓玛 Exp2 后门原理与实践
20155339平措卓玛Exp2 后门原理与实践 基础问题 (1)例举你能想到的一个后门进入到你系统中的可能方式? 答:下载并安装某个程序,这个程序可以正常的并且完整的为我们提供服务,但是在开发改程序 ...
- 洛咕3312 [SDOI2014]数表
洛咕3312 [SDOI2014]数表 终于独立写出一道题了...真tm开心(还是先写完题解在写的) 先无视a的限制,设\(f[i]\)表示i的约数之和 不妨设\(n<m\) \(Ans=\su ...
- Macaca 基础原理浅析
导语 前面几篇文章介绍了在Macaca实践中的一些实用技巧与解决方案,今天简单分析一下Macaca的基础原理.这篇文章将以前面所分享的UI自动化Macaca-Java版实践心得中的demo为基础,进行 ...
- 本地navicat远程连接到云服务器数据库
本来没有开启秘钥的远程服务器端数据库连接非常方便,就在新建连接上填入数据就ok了,但是开启SSH秘钥后的服务器连接有一个大坑,下面来详细讲讲. 其实开启了秘钥,在新建连接下,先选择SSH方式登录到远程 ...
- Java和C#基本类库的区别
java.lang java .net Boolean System.Boolean Byte System. Byte Character System.Char Class System.Type ...
- (幼儿园毕业)Javascript小学级随机生成四则运算
软件工程第二次结对作业四则运算自动生成器网页版 一.题目要求 本次作业要求两个人合作完成,驾驶员和导航员角色自定,鼓励大家在工作期间角色随时互换,这里会布置两个题目,请各组成员根据自己的爱好任选一题. ...
- centos7 部署LNMP
1.安装Nginx 使用Nginx官方提供的rpm包 [root@nginx ~]# cat /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo b ...
- 2019大疆PC软件开发笔试——开关和灯泡两个电路板
题目描述: 小A是一名DIY爱好者,经常制作一些有趣的东西. 今天,小A突然想要来做这样一个东西.小A现在有两块同样大小为n×m,有n×m块大小为1×1小电路板拼成的矩形电路板,假设叫做电路板A和电路 ...