POJ 3683 2-sat
来源:互联网 发布:crt结束tomcat端口 编辑:程序博客网 时间:2024/05/22 14:56
题目链接:http://poj.org/problem?id=3683
题意:每个婚礼有两个时段(婚礼开始,或者结束)可以进行特别仪式,特别仪式必须要有神父在场,神父只有一个,问是否能满足所有婚礼的需求。
规模:( 1 ≤ N ≤ 1000),N场婚礼
类型: 2-sat
分析:这是“大白书”上的2-sat基础。
每场婚礼都只有两个时间段,而且不能冲突,是2-sat的典型模型。
我们将所有不能共存的关系列出,据此建边,跑2-sat就行了。
这里稍微解释一下建边过程:
对于两场婚礼a,b用a表示“婚礼开始时举行仪式”,用(!a)表示“婚礼结束时举行仪式”,b同a;那么我们有四种组合方式:(a,b),(a,!b),(!a,b),(!a,!b)对于每组确定的a,b,我们可以得到这四种组合是否成立。因为求的是2-sat,我们只需要对冲突的组合建边:
时间复杂度&&优化:
代码:
#include <iostream>#include <algorithm>#include <stdio.h>#include <stdlib.h>#include <cstring>using namespace std;const int MAXN=2005;const int MAXM=40000000;int n;struct Time{ int s,t; int l;}time[MAXN];struct Edge{ int to,next;}edge[MAXM];int head[MAXN],tot;void init(){ tot=0; memset(head,-1,sizeof(head));}void add_edge(int u,int v){ edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;}void ADD(int i,int j){ Time a=time[i]; Time b=time[j]; if(min(a.s+a.l,b.s+b.l)>max(a.s,b.s)){ //a=>!b,b=>!a add_edge((2*i),(2*j)^1); add_edge((2*j),(2*i)^1); } if(min(a.s+a.l,b.t)>max(a.s,b.t-b.l)){//cout<<2; add_edge((2*i),2*j); add_edge((2*j)^1,(2*i)^1); } if(min(a.t,b.s+b.l)>max(a.t-a.l,b.s)){//cout<<3; add_edge((2*i)^1,(2*j)^1); add_edge(2*j,2*i); } if(min(a.t,b.t)>max(a.t-a.l,b.t-b.l)){//cout<<4; add_edge((2*i)^1,2*j); add_edge((2*j)^1,2*i); }}bool vis[MAXN];int S[MAXN],top;bool dfs(int u){ if(vis[u^1])return false; if(vis[u])return true; vis[u]=true; S[top++]=u; for(int i=head[u];i!=-1;i=edge[i].next){ if(!dfs(edge[i].to)) return false; } return true;}bool Twosat(int n){ memset(vis,false,sizeof(vis)); for(int i=0;i<n;i+=2){ if(vis[i]||vis[i^1])continue; top=0; if(!dfs(i)){ while(top)vis[S[--top]]=false; if(!dfs(i^1))return false; } } return true;}void solve(){ if(Twosat(2*n)){ printf("YES\n"); for(int i = 0;i < n;i++) if(vis[i*2]){ printf("%02d:%02d %02d:%02d\n",time[i].s/60,time[i].s%60,(time[i].s+time[i].l)/60,(time[i].s+time[i].l)%60); } else{ printf("%02d:%02d %02d:%02d\n",(time[i].t-time[i].l)/60,(time[i].t-time[i].l)%60,time[i].t/60,time[i].t%60); } return; } printf("NO\n");}int main(){ while(scanf("%d",&n)==1){ init(); for(int i=0;i<n;i++){ int a,b,c; scanf("%d:%d",&a,&b); time[i].s=a*60+b; scanf("%d:%d",&a,&b); time[i].t=a*60+b; scanf("%d",&time[i].l); } for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ ADD(i,j); } }// for(int i=0;i<2*n;i++){// cout<<i<<endl;// for(int j=head[i];j!=-1;j=edge[j].next)// printf("%d ",edge[j].to);// cout<<endl;// } solve(); } return 0;}
0 0
- poj 3683【2-SAT】
- poj 3683 2-sat
- poj 3683 2-sat
- poj 3683 2-sat
- POJ 3683 2-sat
- POJ 3683 2-sat
- poj 3683 2-sat
- POJ 3683 2-sat
- POJ-3683(2-SAT)
- poj 3683 2-SAT 拓扑排序输出
- POJ 3683 2-sat 输出解
- POJ 3683 2-SAT +输出方案
- 2-sat 问题 总结 例题poj 3683
- 2-SAT——POJ 3683
- poj 3683 2SAT入门+挑战模板
- POJ 3683 2-SAT 输出可行方案
- 2-sat POJ 3678
- POJ 3207 2-sat
- ArrayList简单使用
- Count and Say
- linux mongodb安装和配置启动图文详解
- 组织图结构图连线
- Java面试准备十五:数据库——索引
- POJ 3683 2-sat
- MySQL数据库下 delete from x where id=?会发生什么锁
- 计算机网络与Internet发展历史
- Python+Selenium框架设计篇之3-什么是POM
- html5+servlet文件上传
- 浮点数的二进制表示(IEEE 754标准)
- K-L变换实现图像压缩
- centos 中英文输入法切换
- 悲观锁与乐观锁