关于two sat算法

关于具体算法

  • 首先此算法只对于存在类似于一个点选了另一个点就不能选这样的条件,并且每个点只有两种状态(一般是选或不选),不然是个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)的更多相关文章

  1. <老友记>学习笔记

    这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...

  2. OGG学习笔记02-单向复制配置实例

    OGG学习笔记02-单向复制配置实例 实验环境: 源端:192.168.1.30,Oracle 10.2.0.5 单实例 目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1. ...

  3. python数据分析入门学习笔记

    学习利用python进行数据分析的笔记&下星期二内部交流会要讲的内容,一并分享给大家.博主粗心大意,有什么不对的地方欢迎指正~还有许多尚待完善的地方,待我一边学习一边完善~ 前言:各种和数据分 ...

  4. 【MarkMark学习笔记学习笔记】javascript/js 学习笔记

    1.0, 概述.JavaScript是ECMAScript的实现之一 2.0,在HTML中使用JavaScript. 2.1 3.0,基本概念 3.1,ECMAScript中的一切(变量,函数名,操作 ...

  5. Linux 学习笔记之超详细基础linux命令 Part 13

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 12---------------- ...

  6. Linux 学习笔记之超详细基础linux命令 Part 8

    Linux学习笔记之超详细基础linux命令 by:授客 QQ:1033553122 ---------------------------------接Part 7----------------- ...

  7. Deep learning with Python 学习笔记(5)

    本节讲深度学习用于文本和序列 用于处理序列的两种基本的深度学习算法分别是循环神经网络(recurrent neural network)和一维卷积神经网络(1D convnet) 与其他所有神经网络一 ...

  8. 【Redis】命令学习笔记——字符串(String)(23个超全字典版)

    Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合). 本篇基于redis 4.0.11版本,学习字符串( ...

  9. programming-languages学习笔记--第3部分

    programming-languages学习笔记–第3部分 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src ...

  10. 学习笔记 - 2sat

    学习笔记 - 2sat 决定重新启用Markdown--只是因为它支持MathJax数学公式 noip考完,既轻松又无奈,回来慢慢填坑 这篇博客也是拖了好久,通过kuangbin的博客才弄懂2-sat ...

随机推荐

  1. 分裂 BZOJ2064 状压DP

    分析: 这个题很好啊,比起什么裸的状压DP高多了! 我们可以考虑,什么时候答案最大:全合并,之后再分裂 这样,我们必定可以得到答案,也就是说答案必定小于n+m 那么我们可以考虑,什么时候能够使答案更小 ...

  2. 网络对抗技术 2017-2018-2 20152515 Exp3 免杀原理与实践

    基础问题回答 (1)杀软是如何检测出恶意代码的? 答:分析恶意程序的行为特征,分析其代码流将其性质归类于恶意代码. (2)免杀是做什么? 答:一般是对恶意软件做处理,让它不被杀毒软件所检测,也是渗透测 ...

  3. 20155226 《网络攻防》 Exp1 PC平台逆向破解(5)M

    20155226 <网络攻防> Exp1 PC平台逆向破解(5)M 实践目标 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串 该程序同时包含另一个代 ...

  4. 20155308『网络对抗技术』Exp7:网络欺诈防范

    20155308『网络对抗技术』Exp7:网络欺诈防范 原理与实践说明 1.实践目标 本实践的目标是:理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法. 2.实践内容概述 简单应用SET ...

  5. Luogu P1993 小 K 的农场

    其实很早以前就打好了,但一直忘记写了. 也就是差分约束的模板题. 关于差分约束,也就是用来求关于一些不等式互相约束算出最优解. 推荐一个讲的很好的博客:http://www.cppblog.com/m ...

  6. mfc CProgressCtrl

    CProgressCtrl常用属性 CProgressCtrl类常用成员函数 CProgressCtrl代码示例 一.CProgressCtrl控件属性 当我们在处理大程序时,常常需要耗很长时间(比如 ...

  7. pycharm自动生成头文件注释

    1.在file->settings->file and code templates->python script即可自定制pycharm创建文件自动生成的头文件注释信息 2.创建p ...

  8. 事务特性,事务的隔离级别,并发事务可能出现的问题,spring事务 数据库锁

    1.0 事务特性(ACID) Atomicity:原子性,一个事务不可以被拆分 Consistency:一致性,在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态, ...

  9. 微信小程序选择并上传图片

      上传图片 API: wx.chooseImage() 和 wx.uploadFile() wx.chooseImage({ count: 1, // 默认9 sizeType: ['origina ...

  10. 美食查询手机应用"吃了么":NABC

    一 N(need) 当你在一个陌生的地方游玩,想吃到当地的招牌美食时怎么办? 当你听说有一个很好吃的家常菜,也想自己下厨试试时怎么办?打印出菜谱,还是奔波于厨房和电脑之前? 查询周边美食的功能对于那些 ...