关于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. zookeeper的原理及使用

    ZooKeeper是Hadoop Ecosystem中非常重要的组件,它的主要功能是为分布式系统提供一致性协调(Coordination)服务,与之对应的Google的类似服务叫Chubby.今天这篇 ...

  2. kettle学习笔记(十)——数据检验、统计、分区与JS脚本

    一.概述 数据剖析和数据检验: 用于数据的检查.清洗 . 统计步骤: 提供数据采样和统计的功能 分区: 根据数据里某个字段的值,拆分成多个数据块.输出到不同的库表和文件中. 脚本: Javascrip ...

  3. 20155330 《网络对抗》 Exp5 MSF基础应用

    20155330 <网络对抗> Exp5 MSF基础应用 实践过程记录 主动攻击实践:MS08_067漏洞攻击 攻击机:kali IP地址:192.168.124.132 靶机:windo ...

  4. Mybatis初步详细配置

    1.Mybatis所需包 下载地址:https://github.com/mybatis/mybatis-3/releases,其中log4j是日志包,mysql是数据库所需包,需自行下载 2.项目结 ...

  5. sql——sql中的各种连接

    现有两张表 tablea 和 tableb     各种连接 1.笛尔卡积 SELECT * FROM TabA a,TabB b where a.id = b.id /*笛尔卡积乘积*/ 返回的结果 ...

  6. onSaveInstanceState和onRestoreInstanceState触发的时机

    先看Application Fundamentals上的一段话: Android calls onSaveInstanceState() before the activity becomes vul ...

  7. ELK安装部署

    一.ELK简介 ELK是Elasticsearch.Logstash.Kibana的简称,这三者是核心套件,但并非全部.Elasticsearch是实时全文搜索和分析引擎,提供搜集.分析.存储数据三大 ...

  8. GitHub 新手教程 四,Git GUI 新手教程(1),OpenSSH Public Key

    1,从开始菜单 启动 Git GUI,或者运行: D:\soft\Git\cmd\git-gui.exe(D:\soft\Git 为您的 GitHub 安装文件夹) 2,获取 SSH 密钥: 3,点击 ...

  9. 《杜增强讲Unity之Tanks坦克大战》4-坦克的移动和旋转

    4 坦克移动和旋转 本节课的目标是实现同时wsad和上下左右控制两个坦克分别移动和旋转 4.1 本节代码预览   image 将上节课场景s2另存为s3. 4.2 添加车轮扬沙效果 从Prefabs里 ...

  10. Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果

    Unity 3D 简易制作摄像机围绕物体随鼠标旋转效果 梗概: 一. 摄像机围绕目标物体旋转, 即摄像机离目标物体有一定的距离且旋转轴心为该物体的位置. 二. 当目标物体被障碍物挡住后, 需要将摄像机 ...