2-SAT 问题
2-SAT 问题是k-SAT问题在k==2时的特殊情况,因为已经证明k>=3时的k-sat问题属于npc问题。所以在这里仅研究2-SAT的特殊情况。
//COGS 313
//by Cydiater
//2016.8.2
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iomanip>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
#define FILE "spo"
;
const int oo=0x3f3f3f3f;
inline int read(){
,f=;
;ch=getchar();}
+ch-';ch=getchar();}
return x*f;
}
,group[MAXN],dfn[MAXN],low[MAXN],dfs_clock=,stack[MAXN],top=,group_num=,du[MAXN],opp[MAXN],LEN=,Link[MAXN],q[MAXN],head,tail,lable[MAXN];
bool vis[MAXN];
],E[MAXN<<];
namespace solution{
inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
inline void Insert(int x,int y){E[++LEN].next=Link[x];Link[x]=LEN;E[LEN].y=y;E[LEN].x=x;}
void init(){
N=read();M=read();N<<=;
up(i,,M){
,y=read()-;
insert(x,y^);
insert(y,x^);
}
}
void tarjan(int node){
dfn[node]=low[node]=++dfs_clock;
stack[++top]=node;vis[node]=;
for(int i=LINK[node];i;i=e[i].next)
if(!dfn[e[i].y]){
tarjan(e[i].y);
low[node]=min(low[node],low[e[i].y]);
}
else if(vis[e[i].y])low[node]=min(low[node],dfn[e[i].y]);
if(low[node]==dfn[node]){
int tmp;
group_num++;
do{
tmp=stack[top--];
vis[tmp]=;
group[tmp]=group_num;
}while(tmp!=node);
}
}
void slove(){
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(group,-,sizeof(group));
memset(du,,sizeof(du));
memset(lable,,sizeof(lable));
up(i,,N-)if(!dfn[i])tarjan(i);
up(i,,N-){
]){
puts("NIE");
exit();
}
opp[group[i]]=group[i^];
opp[group[i^]]=group[i];
}
up(i,,len){
int x=e[i].x,y=e[i].y;
if(group[x]!=group[y]){
Insert(group[y],group[x]);
du[group[x]]++;
}
}
head=;tail=;
up(i,,group_num))q[++tail]=i;
for(;head<=tail;head++){
int node=q[head];
)continue;
lable[node]=;lable[opp[node]]=;
for(int i=Link[node];i;i=E[i].next)
)
q[++tail]=E[i].y;
}
}
void output(){
up(i,,N-))printf();
}
}
int main(){
//freopen("input.in","r",stdin);
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
using namespace solution;
init();
slove();
output();
;
}
//POJ 3207
//by Cydiater
//2016.8.2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <algorithm>
#include <iomanip>
#include <string>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
,f=;
;ch=getchar();}
+ch-';ch=getchar();}
return x*f;
}
,st[MAXN],nd[MAXN],dfn[MAXN],low[MAXN],stack[MAXN],dfs_clock=,top=,group[MAXN],group_num=;
bool vis[MAXN];
];
namespace solution{
inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
void init(){
N=read();M=read();
up(i,,M-){
int x=read(),y=read();
st[i]=min(x,y);nd[i]=max(x,y);
}
}
void build(){
up(i,,M-)up(j,i+,M-){
if((st[i]>st[j]&&st[i]<nd[j]&&nd[i]>nd[j])||(st[j]>st[i]&&st[j]<nd[i]&&nd[j]>nd[i])){
insert(i,j+M);
insert(j+M,i);
insert(j,i+M);
insert(i+M,j);
}
}
}
void tarjan(int node){
low[node]=dfn[node]=++dfs_clock;
vis[node]=;stack[++top]=node;
for(int i=LINK[node];i;i=e[i].next)
if(!dfn[e[i].y]){
tarjan(e[i].y);
low[node]=min(low[node],low[e[i].y]);
}
else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
if(low[node]==dfn[node]){
int tmp;group_num++;
do{
tmp=stack[top--];
vis[tmp]=;
group[tmp]=group_num;
}while(tmp!=node);
}
}
bool check(){
up(i,,M);
;
}
void slove(){
build();
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
up(i,,M<<)if(!dfn[i])tarjan(i);
if(check())puts("panda is telling the truth...");
else puts("the evil panda is lying again");
}
}
int main(){
//freopen("input.in","r",stdin);
using namespace solution;
init();
slove();
;
}
//POJ 3683
//by Cydiater
//2016.8.2
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <map>
#include <algorithm>
#include <ctime>
#include <map>
#include <iomanip>
#include <cstring>
#include <string>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
,f=;
;ch=getchar();}
+ch-';ch=getchar();}
return x*f;
}
,dfn[MAXN],low[MAXN],dfs_clock=,stack[MAXN],top=,group[MAXN],group_num=,opp[MAXN],Link[MAXN],LEN=,du[MAXN],q[MAXN<<],head=,tail=;
int lable[MAXN];
bool vis[MAXN];
struct edge{int x,y,next;}e[MAXN*MAXN],E[MAXN*MAXN];
namespace solution{
inline bool check(int st1,int nd1,int st2,int nd2){return (nd1<=st2)||(nd2<=st1);}
inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
inline void Insert(int x,int y){E[++LEN].next=Link[x];Link[x]=LEN;E[LEN].y=y;E[LEN].x=x;}
inline void print(int a,int b){
)printf("0%d:",a);
else printf("%d:",a);
)printf("0%d",b);
else printf("%d",b);
printf(" ");
}
void init(){
N=read();
up(i,,N){
int h1,m1,t1,h2,m2,t2,d;
scanf("%d:%d",&h1,&m1);
t1=h1*+m1;
scanf("%d:%d",&h2,&m2);
t2=h2*+m2;
st[i]=t1;nd[i]=t2;c[i]=read();
}
}
void build(){
up(i,,N)up(j,i+,N){
if(!check(st[i],st[i]+c[i],st[j],st[j]+c[j])){
insert(i,j+N);
insert(j,i+N);
}
if(!check(st[i],st[i]+c[i],nd[j]-c[j],nd[j])){
insert(i,j);
insert(j+N,i+N);
}
if(!check(nd[i]-c[i],nd[i],st[j],st[j]+c[j])){
insert(i+N,j+N);
insert(j,i);
}
if(!check(nd[i]-c[i],nd[i],nd[j]-c[j],nd[j])){
insert(i+N,j);
insert(j+N,i);
}
}
}
void tarjan(int node){
dfn[node]=low[node]=++dfs_clock;
vis[node]=;stack[++top]=node;
for(int i=LINK[node];i;i=e[i].next)
if(!dfn[e[i].y]){
tarjan(e[i].y);
low[node]=min(low[node],low[e[i].y]);
}
else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
if(low[node]==dfn[node]){
int tmp;group_num++;
do{
tmp=stack[top--];
vis[tmp]=;
group[tmp]=group_num;
}while(tmp!=node);
}
}
void re_build(){
up(i,,N){
if(group[i]==group[i+N]){
puts("NO");
exit();
}
opp[group[i]]=group[i+N];
opp[group[i+N]]=group[i];
}
puts("YES");
up(i,,len){
int x=e[i].x,y=e[i].y;
if(group[x]==group[y])continue;
Insert(group[y],group[x]);
du[group[x]]++;
}
}
void downit(int node){
if(lable[node])return;
lable[node]=-;
for(int i=Link[node];i;i=E[i].next)
downit(E[i].y);
}
void top_sort(){
head=;tail=;
up(i,,group_num))q[++tail]=i;
for(;head<=tail;head++){
int node=q[head];
if(lable[node])continue;
lable[node]=;downit(opp[node]);
for(int i=Link[node];i;i=E[i].next)
)
q[++tail]=E[i].y;
}
}
void slove(){
memset(vis,,sizeof(vis));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(du,,sizeof(du));
memset(lable,,sizeof(lable));
build();
up(i,,N<<)if(!dfn[i])tarjan(i);
re_build();
top_sort();
}
void output(){
up(i,,N){
){print(st[i]/,st[i]%);printf(,(st[i]+c[i])%);}
,(nd[i]-c[i])%);printf(,nd[i]%);}
printf("\n");
}
}
}
int main(){
freopen("input.in","r",stdin);
using namespace solution;
init();
slove();
output();
;
}
if(op==1&&res==1){
insert(x,x+N);
insert(y,y+N);
}
2.op==XOR是不需要连边的。
//POJ 3678
//by Cydiater
//2016.8.3
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <queue>
#include <map>
#include <algorithm>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
;
const int oo=0x3f3f3f3f;
inline int read(){
,f=;
;ch=getchar();}
+ch-';ch=getchar();}
return x*f;
}
,dfn[MAXN],low[MAXN],stack[MAXN],top=,dfs_clock=,group_num=,group[MAXN];
bool vis[MAXN];
string s;
map<string,int>m;
struct edge{
int x,y,next;
}e[MAXN<<];
namespace solution{
inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}
void init(){
m[;m[;m[;
N=read();M=read();
up(i,,M){
int x=read(),y=read(),res=read();cin>>s;
int op=m[s];
&&res==){
insert(x,x+N);
insert(y,y+N);
}
&&res==){
insert(x+N,y);
insert(y+N,x);
}
&&res==){
insert(x,y+N);
insert(y,x+N);
}
&&res==){
insert(x+N,x);
insert(y+N,y);
}
&&res==){
insert(x,y+N);
insert(y,x+N);
insert(y+N,x);
insert(x+N,y);
}
&&res==){
insert(x,y);
insert(y,x);
insert(x+N,y+N);
insert(y+N,x+N);
}
}
}
void tarjan(int node){
dfn[node]=low[node]=++dfs_clock;
stack[++top]=node;vis[node]=;
for(int i=LINK[node];i;i=e[i].next)
if(!dfn[e[i].y]){
tarjan(e[i].y);
low[node]=min(low[node],low[e[i].y]);
}else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
if(low[node]==dfn[node]){
group_num++;
int tmp;
do{
tmp=stack[top--];
vis[tmp]=;
group[tmp]=group_num;
}while(tmp!=node);
}
}
bool check(){
up(i,,N-);
;
}
void slove(){
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
up(i,,N<<)if(!dfn[i])tarjan(i);
if(check())puts("YES");
else puts("NO");
}
}
int main(){
//freopen("input.in","r",stdin);
using namespace solution;
init();
slove();
;
}
//POJ 2749
//by Cydiater
//2016.8.8
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <iomanip>
#include <ctime>
#include <cmath>
#include <cstdlib>
using namespace std;
#define ll long long
#define up(i,j,n) for(int i=j;i<=n;i++)
#define down(i,j,n) for(int i=j;i>=n;i--)
typedef pair<int,int> pii;
;
const int oo=0x3f3f3f3f;
inline int read(){
,f=;
;ch=getchar();}
+ch-';ch=getchar();}
return x*f;
}
pii S1,S2,node[MAXN],hate[MAXN],fri[MAXN];
int N,A,B,leftt,rightt,mid,LINK[MAXN],len,dfn[MAXN],low[MAXN],stack[MAXN],top,dfs_clock,group[MAXN],group_num;
bool vis[MAXN];
];
namespace solution{
inline int dist(pii a,pii b){return abs(a.first-b.first)+abs(a.second-b.second);}
inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;e[len].x=x;}
void init(){
N=read();A=read();B=read();
int x=read(),y=read();
S1=make_pair(x,y);
x=read();y=read();
S2=make_pair(x,y);
up(i,,N){
int x=read(),y=read();
node[i]=make_pair(x,y);
}
up(i,,A){
int x=read(),y=read();
hate[i]=make_pair(x,y);
}
up(i,,B){
int x=read(),y=read();
fri[i]=make_pair(x,y);
}
}
void tarjan(int node){
stack[++top]=node;vis[node]=;
low[node]=dfn[node]=++dfs_clock;
for(int i=LINK[node];i;i=e[i].next)
if(!dfn[e[i].y]){
tarjan(e[i].y);
low[node]=min(low[node],low[e[i].y]);
}else if(vis[e[i].y]) low[node]=min(low[node],dfn[e[i].y]);
if(dfn[node]==low[node]){
group_num++;int tmp;
do{
tmp=stack[top--];
vis[tmp]=;
group[tmp]=group_num;
}while(tmp!=node);
}
}
bool check(int lim){
len=;top=;dfs_clock=;group_num=;
memset(LINK,,sizeof(LINK));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
up(i,,A){
int x=hate[i].first,y=hate[i].second;
insert(x,y+N);
insert(y,x+N);
insert(x+N,y);
insert(y+N,x);
}
up(i,,B){
int x=fri[i].first,y=fri[i].second;
insert(x,y);
insert(y,x);
insert(x+N,y+N);
insert(y+N,x+N);
}
up(i,,N)up(j,i+,N){
if(dist(node[i],S1)+dist(S1,node[j])>lim){
insert(i,j+N);
insert(j,i+N);
}
if(dist(node[i],S2)+dist(S2,node[j])>lim){
insert(i+N,j);
insert(j+N,i);
}
if(dist(node[i],S1)+dist(S1,S2)+dist(S2,node[j])>lim){
insert(i,j);
insert(j+N,i+N);
}
if(dist(node[i],S2)+dist(S1,S2)+dist(S1,node[j])>lim){
insert(i+N,j+N);
insert(j,i);
}
}
up(i,,N<<)if(!dfn[i])tarjan(i);
up(i,,N);
;
}
void slove(){
leftt=;rightt=;
<rightt){
mid=(leftt+rightt)>>;
if(check(mid)) rightt=mid;
else leftt=mid;
}
if((!check(leftt))&&(!check(rightt)))puts("-1");
else if(check(leftt)) printf("%d\n",leftt);
else printf("%d\n",rightt);
}
}
int main(){
//freopen("input.in","r",stdin);
using namespace solution;
init();
slove();
;
}
2-SAT 问题的更多相关文章
- 多边形碰撞 -- SAT方法
检测凸多边形碰撞的一种简单的方法是SAT(Separating Axis Theorem),即分离轴定理. 原理:将多边形投影到一条向量上,看这两个多边形的投影是否重叠.如果不重叠,则认为这两个多边形 ...
- POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang
Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...
- Map Labeler POJ - 2296(2 - sat 具体关系建边)
题意: 给出n个点 让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...
- 学习笔记(two sat)
关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...
- LA 3211 飞机调度(2—SAT)
https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...
- HIT 1917 2—SAT
题目大意:一国有n个党派,每个党派在议会中都有2个代表, 现要组建和平委员会,要从每个党派在议会的代表中选出1人,一共n人组成和平委员会. 已知有一些代表之间存在仇恨,也就是说他们不能同时被选为和平委 ...
- 2 - sat 模板(自用)
2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一 POJ 3207 Ikki's Story IV ...
- SAT考试里最难的数学题? · 三只猫的温暖
问题 今天无意中在Quora上看到有人贴出来一道号称是SAT里最难的一道数学题,一下子勾起了我的兴趣.于是拿起笔来写写画画,花了差不多十五分钟搞定.觉得有点意思,决定把解题过程记下来.原帖的图太小,我 ...
- 世界碰撞算法原理和总结(sat gjk)
序言 此文出于作者的想法,从各处文章和论文中,总结和设计项目中碰撞结构处理方法.如有其它见解,可以跟作者商讨.(杨子剑,zijian_yang@yeah.net). 在一个世界中,有多个物体,物体可以 ...
- hdu 4115 (2—SAT)
题意:两个人石头剪刀布,一个人的出法已确定,另一个人的出法有一定约束,某两次要相同或者不同,问你第二个人能否全部都不失败. 思路:根据Bob出的情况,我们可以确定每次Alice有两种方案. R与P,S ...
随机推荐
- hibernate Expression详解
关键字: hibernate expression hibernate Expression详解Expression.gt:对应SQL条件中的"field > value " ...
- C#迭代器
迭代器概述 迭代器是可以返回相同类型的值的有序序列的一段代码. 迭代器可用作方法.运算符或 get 访问器的代码体. 迭代器代码使用 yield return 语句依次返回每个元素.yield bre ...
- java中的static详解
如果一个类成员被声明为static,它就能够在类的任何对象创建之前被访问,而不必引用任何对象.static 成员的最常见的例子是main( ) .因为在程序开始执行时必须调用main() ,所以它被声 ...
- 关于浏览器URL中出现会话验证字符说明
服务器安装了网站安全狗,访问网站的时候会显示一串类似iissafedogccsision=7Z86v5H5z这样的会话验证信息. 安全狗官方解释 出现该字符的主要原因是用户开启了网站安全狗的CC防护的 ...
- 71 fdisk-Linux 的磁盘分区表操作工具。
语法: fdisk [-l] 装置名称 选项与参数: -l :输出后面接的装置所有的分区内容.若仅有 fdisk -l 时, 则系统将会把整个系统内能够搜寻到的装置的分区均列出来. 实例 列出所有分区 ...
- Android四大组件之Activity详解——传值和获取结果
废话不多说,先来看效果图 项目源码: http://download.csdn.net/detail/ginodung/8331535 程序说明: 在MainActivity中输入用户名和密码,然后提 ...
- 最棒的10款MySQL GUI工具
绝大多数的关系数据库都明显不同于MS Access,它们都有两个截然不同的部分:后端作为数据仓库,前端作为用于数据组件通信的用户界面.这种设计非常巧妙,它并行处理两层编程模型,将数据 层从用户界面中分 ...
- 转 Linux日志文件系统及性能分析
日志文件系统可以在系统发生断电或者其它系统故障时保证整体数据的完整性,Linux是目前支持日志文件系统最多的操作系统之一,本文重点研究了Linux常用的日志文件系统:EXT3.ReiserFS.XFS ...
- 本机ubuntu链接阿里云服务器(也是ubuntu)
首先在本机安装ssh工具,并修改配置文件(参考:http://www.cnblogs.com/herd/p/5009067.html) 第一步:ssh 100.121.156.32(即:服务器的ip地 ...
- 安装centos虚拟机
启动虚拟机提示"无法连接虚拟设备ide1:0,主机上没有相对应的设备" 进入编辑虚拟机设置--选中硬盘--点高级--在 虚拟机设备节点中选ide0:0接行了.