Poj 3683-Priest John's Busiest Day 2-sat,拓扑排序
|
Priest John's Busiest Day
Description John is the only priest in his town. September 1st is the John's busiest day in a year because there is an old legend in the town that the couple who get married on that day will be forever blessed by the God of Love. This year N couples plan to get married on the blessed day. The i-th couple plan to hold their wedding from time Si to time Ti. According to the traditions in the town, there must be a special ceremony on which the couple stand before the priest and accept blessings. The i-th couple need Di minutes to finish this ceremony. Moreover, this ceremony must be either at the beginning or the ending of the wedding (i.e. it must be either from Si to Si + Di, or from Ti - Di to Ti). Could you tell John how to arrange his schedule so that he can present at every special ceremonies of the weddings. Note that John can not be present at two weddings simultaneously. Input The first line contains a integer N ( 1 ≤ N ≤ 1000). Output The first line of output contains "YES" or "NO" indicating whether John can be present at every special ceremony. If it is "YES", output another N lines describing the staring time and finishing time of all the ceremonies. Sample Input 2 Sample Output YES Source POJ Founder Monthly Contest – 2008.08.31, Dagger and Facer
|
||||||||||
题意:有n对人要结婚,牧师分别去主持每个婚礼中的仪式,给出每对新人的开始和结束时间,还有仪式需要的时间,仪式必须要在开始或结束的时间举办,问是否能给出一种方案,使得牧师可以参加所有仪式。
题解:
2-sat。。。
终于把这道题A了。。。
首先,先把每个婚礼的每一段开始时间标记为i*2,结束时间标记为i*2-1。然后缩点,逆向用强联通分量建图。然后用拓扑排序做一遍,输出即可。
安利一个2-sat讲解:2-sat总结
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2010
struct node
{
int begin,end,next;
}edge[*MAXN*MAXN];
struct NODE
{
int begin,end,next;
}edge1[*MAXN*MAXN];
int cnt,Head[MAXN],cnt1,Head1[MAXN],n,s1[MAXN],t1[MAXN],LOW[MAXN],DFN[MAXN],STACK[MAXN],color[MAXN],q[MAXN],op[MAXN],belong[MAXN],SCC,Id[MAXN],SIZE,top,N;
bool INSTACK[MAXN];
void addedge(int bb,int ee)
{
edge[++cnt].begin=bb;edge[cnt].end=ee;edge[cnt].next=Head[bb];Head[bb]=cnt;
}
void addedge1(int bb,int ee)
{
edge1[++cnt1].begin=bb;edge1[cnt1].end=ee;edge1[cnt1].next=Head1[bb];Head1[bb]=cnt1;
}
int read()
{
int s=,fh=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')fh=-;ch=getchar();}
while(ch>=''&&ch<=''){s=s*+(ch-'');ch=getchar();}
return s*fh;
}
int Judge(int ii,int jj)
{
if(s1[jj]>=t1[ii]||s1[ii]>=t1[jj])return ;
return ;
}
void Build()
{
int i,j;
memset(Head,-,sizeof(Head));cnt=;
for(i=;i<=n;i++)
{
for(j=i+;j<=n;j++)
{
if(Judge(*i,*j)==)
{
addedge(*i,*j-);
addedge(*j,*i-);
}
if(Judge(*i,*j-)==)
{
addedge(*i,*j);
addedge(*j-,*i-);
}
if(Judge(*i-,*j)==)
{
addedge(*i-,*j-);
addedge(*j,*i);
}
if(Judge(*i-,*j-)==)
{
addedge(*i-,*j);
addedge(*j-,*i);
}
}
}
}
void Tarjan(int u)
{
int i,v;
LOW[u]=DFN[u]=++SIZE;
STACK[top++]=u;INSTACK[u]=true;
for(i=Head[u];i!=-;i=edge[i].next)
{
v=edge[i].end;
if(!DFN[v])
{
Tarjan(v);
LOW[u]=min(LOW[u],LOW[v]);
}
else if(INSTACK[v]==true)LOW[u]=min(LOW[u],DFN[v]);
}
if(LOW[u]==DFN[u])
{
SCC++;
do
{
v=STACK[--top];
INSTACK[v]=false;
belong[v]=SCC;
}while(u!=v);
}
}
void solve()
{
SIZE=;
for(int i=;i<=N;i++)if(!DFN[i])Tarjan(i);
}
void dfs(int u)
{
if(color[u]!=)return;
color[u]=-;
for(int i=Head1[u];i!=-;i=edge1[i].next)dfs(edge1[i].end);
}
void Toposort()
{
int head=,tail=,i,u,v;
for(i=;i<=SCC;i++)if(Id[i]==)q[++tail]=i;
while(head<=tail)
{
u=q[++head];
if(color[u]!=)continue;//已经被标记过就不用搜索了.
color[u]=;/*若将color[]标记为,代表被标记为选择(即1).*/dfs(op[u]);/*将和u对立的点标记为选择u的对立点(即-1).*/
for(i=Head1[u];i!=-;i=edge1[i].next)
{
v=edge1[i].end;
Id[v]--;if(Id[v]==)q[++tail]=v;
}
}
}
void write(int k)
{
printf("%.2d:",k/);
printf("%.2d",k%);
}
int main()
{
int S1,S2,T1,T2,D,i;
n=read();
N=;
for(i=;i<=n;i++)
{
S1=read();S2=read();T1=read();T2=read();D=read();
s1[++N]=S1*+S2;t1[N]=s1[N]+D;
t1[++N]=T1*+T2;s1[N]=t1[N]-D;
}
Build();
solve();
for(i=;i<=n;i++)if(belong[*i-]==belong[*i]){printf("NO");return ;}
memset(Head1,-,sizeof(Head1));cnt1=;
for(i=;i<=cnt;i++)
{
if(belong[edge[i].begin]!=belong[edge[i].end]){addedge1(belong[edge[i].end],belong[edge[i].begin]);Id[belong[edge[i].begin]]++;}
}
memset(color,,sizeof(color));
for(i=;i<=n;i++)
{
op[belong[*i]]=belong[*i-];
op[belong[*i-]]=belong[*i];
}
Toposort();
printf("YES");
for(i=;i<=n;i++)
{
printf("\n");
if(color[belong[i*]]==){write(s1[i*]);printf(" ");write(t1[i*]);}
else {write(s1[i*-]);printf(" ");write(t1[i*-]);}
}
fclose(stdin);
fclose(stdout);
return ;
}
Poj 3683-Priest John's Busiest Day 2-sat,拓扑排序的更多相关文章
- POJ 3683 Priest John's Busiest Day / OpenJ_Bailian 3788 Priest John's Busiest Day(2-sat问题)
POJ 3683 Priest John's Busiest Day / OpenJ_Bailian 3788 Priest John's Busiest Day(2-sat问题) Descripti ...
- POJ 3683 Priest John's Busiest Day(2-SAT+方案输出)
Priest John's Busiest Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10010 Accep ...
- POJ 3683 Priest John's Busiest Day (2-SAT)
Priest John's Busiest Day Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 6900 Accept ...
- POJ 3683 Priest John's Busiest Day(2-SAT 并输出解)
Description John is the only priest in his town. September 1st is the John's busiest day in a year b ...
- poj - 3683 - Priest John's Busiest Day(2-SAT)
题意:有N场婚礼,每场婚礼的开始时间为Si,结束时间为Ti,每场婚礼有个仪式,历时Di,这个仪式要么在Si时刻开始,要么在Ti-Di时刻开始,问能否安排每场婚礼举行仪式的时间,使主持人John能参加所 ...
- POJ 3683 Priest John's Busiest Day (2-SAT)
题意:有n对新人要在同一天结婚.结婚时间为Ti到Di,这里有时长为Si的一个仪式需要神父出席.神父可以在Ti-(Ti+Si)这段时间出席也可以在(Di-Si)-Si这段时间.问神父能否出席所有仪式,如 ...
- POJ 3683 Priest John's Busiest Day (2-SAT,常规)
题意: 一些人要在同一天进行婚礼,但是牧师只有1个,每一对夫妻都有一个时间范围[s , e]可供牧师选择,且起码要m分钟才主持完毕,但是要么就在 s 就开始,要么就主持到刚好 e 结束.因为人数太多了 ...
- POJ 3683 Priest John's Busiest Day
2-SAT简单题,判断一下两个开区间是否相交 #include<cstdio> #include<cstring> #include<cmath> #include ...
- POJ 3683 Priest John's Busiest Day[2-SAT 构造解]
题意: $n$对$couple$举行仪式,有两个时间段可以选择,问是否可以不冲突举行完,并求方案 两个时间段选择对应一真一假,对于有时间段冲突冲突的两人按照$2-SAT$的规则连边(把不冲突的时间段连 ...
- POJ 3683 Priest John's Busiest Day 【2-Sat】
这是一道裸的2-Sat,只要考虑矛盾条件的判断就好了. 矛盾判断: 对于婚礼现场 x 和 y,x 的第一段可以和 y 的第一段或者第二段矛盾,同理,x 的第二段可以和 y 的第一段或者第二段矛盾,条件 ...
随机推荐
- linux - 创建用户
apt-get update apt-get upgrade root@iZ28t2p7lz9Z:~# adduser cuiAdding user `cui' ...Adding new group ...
- jquery ajax 的data 存表单的值
jsp <body> <form action="" method="post" id="formid"> < ...
- 关于datagridview单元格不切换焦点无法获得新输入数据的问题解决方法
问题描述:将EXCEL中的数据导入到dataGridView中,然后通过点击toolStripButton对dataGrideView中的数据进行处理,在测试时,向dataGridView中的某个单元 ...
- Laravel 5.1 事件、事件监听的简单应用
有时候当我们单纯的看 Laravel 手册的时候会有一些疑惑,比如说系统服务下的授权和事件,这些功能服务的应用场景是什么,其实如果没有经历过一定的开发经验有这些疑惑是很正常的事情,但是当我们在工作 ...
- MAC 终端快捷建
常用的快捷键: Ctrl + d 删除一个字符,相当于通常的Delete键(命令行若无所有字符,则相当于exit:处理多行标准输入时也表示eof) Ctrl + h 退格删 ...
- 【 java版坦克大战--事件处理】 坦克动起来了
折腾了这么久,坦克总算能动了.只贴代码编辑不给上首页,花了半个小时的时间写了n多注释. 再顺便把绘图的原理发在这里: 绘图原理 Component类提供了两个和绘图有关的重要方法: ① paint ...
- Leaflet学习笔记-基础内容
为什么选择Leaflet 开源,且代码仅有 31 KB,但它具有开发人员开发在线地图的大部分功能(80%的功能) 是不是比arcgis要小很多呢 官网:http://leafletjs.com/ 劣势 ...
- css 浮动 相对定位 绝对定位区别
今天下班在地铁上看了一个样式教学视频,因为最近在学习前端.以前刚毕业的时候,感觉后台才是王道,但最近发现,前端也很重要,比如:自己接一些私单做的时候,自己要根据需求做好界面,才能更加符合客户需求,不然 ...
- smarty 比较运算符对照表
smarty 比较运算符对照表 运算符 中文解释 eq 相等 ne.neq 不相等 gt 大于 lt 小于 gte.ge 大于等于 lte.le 小于等于 not 非 mod 求模 is [not] ...
- python和django的一些小技巧(locals()...)
locals() 技巧: 思考一下我们对 current_datetime 的最后一次赋值: >>> import datetime >>> def current ...