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 ...
随机推荐
- 自己留存:小经验在asp.net 4.5或者asp.net mvc 5解决A potentially dangerous Request.Form value was detected from the client
以前的解决办法是 <configuration> <system.web> <pages validateRequest="false&q ...
- Python使用基础
1) 基本概念1.1 常量 Python没有提供常量保留字,需要自行扩展一个常量类来实现常量功能 class _const: class ConstError(TypeError):pass def ...
- mysql找回密码
1.打开任务管理器,关闭mysqld.exe 2.win+r运行cmd打开控制台,输入mysqld --skip-grant-tables启动服务器 3.win+r重新运行cmd打开控制台,输入mys ...
- Vim块注释
如何在VIM下快速注释块代码 添加块注释 01.进入视图模式 v进入视图模式,控制方向键选中注释的代码 02.进入列模式并插入# ctrl+v进入列,I插入注释# 03.全部注释 esc两次自动全部注 ...
- Collection中list集合的应用常见的方法
集合 : 用存放对象的容器(集合) Collection : 跟接口 : 单列集合 ---> List :有序的 ,元素是可以重复的. ---> ...
- SharePoint配置搜索服务和指定搜索范围
转载:http://constforce.blog.163.com/blog/static/163881235201201211843334/ 一.配置SharePoint Foundation搜索 ...
- 【CodeVS 2822】爱在心中
“每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home.” 在爱的国度里有N个人,在他们的心中都有着一个 ...
- 【BZOJ 4568】【SCOI 2016】幸运数字
写了一天啊,调了好久,对拍了无数次都拍不出错来(数据生成器太弱了没办法啊). 错误1:把线性基存成结构体,并作为函数计算,最后赋值给调用函数的变量时无疑加大了计算量导致TLE 错误2:像这种函数(A, ...
- spoj687 后缀数组重复次数最多的连续重复子串
REPEATS - Repeats no tags A string s is called an (k,l)-repeat if s is obtained by concatenating k& ...
- Linux下磁盘分区挂载
一般你去买vps都会看到介绍说硬盘多少G 比如 80G 但是你进入系统df -h的时候发现怎么只有10G呢, 其实这10G是用来装系统的和一些常用服务软件的 不是给你放网站数据的 那50G硬盘在哪 ...