题目

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).
The next N lines contain the Si, Ti and Di. Si and Ti are in the format of hh:mm.

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
08:00 09:00 30
08:15 09:00 20

Sample Output

YES
08:00 08:30
08:40 09:00


题意

(我尽然没用Goggle翻译就看懂了题目)
我大致翻译一下:
有一个小镇上只有一个牧师。这个小镇上有一个传说,在九月一日结婚的人会受到爱神的保佑,但是要牧师举办一个仪式。这个仪式要么在婚礼刚刚开始的时候举行,要么举行完婚礼正好结束。
现在已知有n场婚礼,告诉你每一场的开始和结束时间,以及举行仪式所需要的时间。问牧师能否参加所有的婚礼,如果能则输出一种方案。


解决

可能上面的题意还没讲清楚,先上一张图。

现在应该就非常清楚了。
继续化简题目:有n*2条线段,其中每两条(我设的是i和i+n)中只能够选择一条,问能否给出n条线段使得任意两条不存在交点。

一组(或者一个)东西有且仅有两种选择,要么选这个,要么选那个,还有一堆的约束条件。
这是一个很明显的2-sat问题。

(如果对于2-sat问题一脸懵逼,建议回去看另外两道题【按难度、分先后】)
【POI2001】和平委员会

http://blog.csdn.net/qq_30974369/article/details/73927421
【POJ3207】Ikki's Story IV - Panda's Trick
http://blog.csdn.net/qq_30974369/article/details/73930235


这题跟POJ 3207(就是上面的第二个链接) 神似,时间依旧只是一个媒介,对于所有的某两个仪式的时间段(i,j),如果存在重合,则连边(i,j’)【因为是依次枚举任意两个时间段,所以在枚举到(j,i)是会建边(j,i’)】

存在重合的情况也跟POJ 3207神似。。。

看到没,还是两个时间点交叉出现的时候存在重合
只需要加判断是否重合然后建边了。

接下来的一步和POJ 3207 也是一样的,Tarjan缩点,判断是否可行

但是,这题多一个步骤,要求出一组可行性解。
根据Dalao的Blog(在上面的第一个链接里面有dalao博客的链接),这一步应该进行拓扑排序,然后依次尝试染色(此时必定有解)即可。

这题就讲这么多,其他的具体实现参考一下代码。

/*POJ 3683 Priest John's Busiest Day题目大意:
(我竟然没用翻译就看懂了题目)
一个牧师要给n个婚礼进行一个仪式
给定婚礼开始的时间和结束的时间
仪式要么在婚礼刚刚开始的时候进行,要么进行完婚礼正好结束
问牧师能否参加所有的婚礼
并输出方案思路:
跟POJ 3207神似的一道题目
依旧是把题目转化为2-sat来做
这题的时间也是一个媒介
如果某两个婚礼进行仪式的时间有重合,
那么就存在了矛盾关系,通过这些关系连边
Tarjan缩点,判断
拓扑排序染色(把仪式在 开始/结束 进行染色)
最后输出解即可 */#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;const int MAX=10500;int Col[MAX],In[MAX],len[MAX],Opp[MAX];
int s[MAX],G[MAX],dfn[MAX],low[MAX];
int group=0,top=0,tim=0;
bool vis[MAX];
int n;
vector<int> E[MAX];//超级点就用vector来存边,方便些 struct Time
{int b,e;//b表示开始时间,e表示结束时间
}t[MAX];
struct Node
{int v,next;
}e[MAX*MAX];//跑Tarjan时用来存边的邻接表 int h[MAX],cnt=0;//邻接表存储 void Add(int u,int v);//连边,从u->v
void Link();//连边
bool Wrong(int i,int j);//检查两个时间是否矛盾
void Tarjan(int u);//缩点
void Top();//拓扑排序 int main()
{while(cin>>n){memset(h,-1,sizeof(h));cnt=0;tim=group=top=0;memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(In,0,sizeof(In));memset(vis,0,sizeof(vis));memset(Opp,0,sizeof(Opp));for(int i=1;i<=n;++i){int a,b,c,d,e;scanf("%d:%d %d:%d %d",&a,&b,&c,&d,&len[i]);//这里都把时间转化为分钟来计算 t[i].b=a*60+b;t[i+n].e=c*60+d;t[i].e=t[i].b+len[i];//计算开头的结束时间 t[i+n].b=t[i+n].e-len[i];//计算结尾的开始时间 //i   表示第i个婚礼的仪式在开始的时候举行//i+m 表示第i个婚礼的仪式在结束的时候举行 }Link();//连边 for(int i=1;i<=2*n;++i)//缩点 if(!dfn[i])Tarjan(i);for(int i=1;i<=n;++i)//判断是否有解 {if(G[i]==G[i+n])//某个婚礼的 开始/结束 在同一个强连通分量中,无解 {cout<<"NO"<<endl;return 0;}Opp[G[i]]=G[i+n];//存一下超级点的的对立点 Opp[G[i+n]]=G[i];//反向也要存 }cout<<"YES"<<endl;//不存在矛盾,则有解 Top();//Top排序 for(int i=1;i<=n;++i){if(Col[G[i]]==1)//选择了再婚礼开始时 printf("%.2d:%.2d %.2d:%.2d\n",t[i].b/60,t[i].b%60,t[i].e/60,t[i].e%60);else //在婚礼结束时 printf("%.2d:%.2d %.2d:%.2d\n",t[i+n].b/60,t[i+n].b%60,t[i+n].e/60,t[i+n].e%60);}}}inline void Add(int u,int v)//连边,从u->v
{e[cnt]=(Node){v,h[u]};h[u]=cnt++;
}bool Wrong(int i,int j)//判断两个时间是否矛盾
{if(t[i].b>=t[j].e||t[i].e<=t[j].b)return false;elsereturn true;//只要某一个结束时间在另一个的开始时间之前则无矛盾//反之必定存在矛盾
}void Link()//连边
{for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)//枚举任意两组仪式的时间,查看是否存在矛盾  {if(i==j)continue;//自己和自己没有比较的意义 if(Wrong(i,j))//开头和开头矛盾Add(i,j+n);if(Wrong(i,j+n))//开头和结尾矛盾 Add(i,j);if(Wrong(i+n,j))//结尾和开头矛盾 Add(i+n,j+n);if(Wrong(i+n,j+n))//结尾和结尾矛盾 Add(i+n,j);}
}void Tarjan(int u)//缩点
{dfn[u]=low[u]=++tim;s[++top]=u;vis[u]=true;int v;for(int i=h[u];i!=-1;i=e[i].next){v=e[i].v;if(!dfn[v]){Tarjan(v);low[u]=min(low[u],low[v]);}elseif(vis[v])low[u]=min(low[u],dfn[v]);}if(low[u]==dfn[u]){++group;do{v=s[top--];vis[v]=false;G[v]=group;}while(v!=u&&top);}
}void Top()//拓扑排序
{memset(In,0,sizeof(In));//存入度 memset(Col,-1,sizeof(Col));//存颜色for(int i=1;i<=2*n;++i)//连接超级点 {for(int j=h[i];j!=-1;j=e[j].next)//枚举邻边 {int v=e[j].v;if(G[i]==G[v])continue;//在同一个强连通分量中无需考虑 E[G[v]].push_back(G[i]);//边要反着存 In[G[i]]++;//统计入度 }}queue<int> Q;//拓扑排序的队列 for(int i=1;i<=group;++i)if(In[i]==0)Q.push(i);//入度为0的进队 while(!Q.empty()){int v=Q.front();Q.pop();if(Col[v]==-1)//未染色{Col[v]=1;     //染为1 Col[Opp[v]]=0;//对立点染为0 }for(int i=0;i<E[v].size();++i)//依次减入度 {In[E[v][i]]--;if(In[E[v][i]]==0)//入度为0 Q.push(E[v][i]);}}
}
/*
写在AC后面:
这几道2-sat题真是花式出错
这道的错误是缩点以后,并不是按照超级点来输出(明显会挂呀)
然而。。。查了1小时的错
感叹一句:对拍真是利器也。。。
*/

【POJ3683】Priest John's Busiest Day相关推荐

  1. 2190: 【USACO】Farmer John has no Large Brown Cow

    2190: [USACO]Farmer John has no Large Brown Cow 时间限制: 1.000 Sec  内存限制: 64 MB 提交: 16  解决: 12 [命题人:][下 ...

  2. [题解]POJ 3683 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 ...

  3. 【2-SAT初学+模板题讲解】POJ3683 Priest John's Busiest Day

    什么是2-SAT? SAT是适定性(Satisfiability)问题的简称 .一般形式为k-适定性问题,简称 k-SAT. 可以证明,当k>2时,k-SAT是NP完全的.因此一般讨论的是k=2 ...

  4. poj3683 Priest John's Busiest Day

    输出方案的2-sat 直接比较两个点强联通分量的编号,缩完点的图应该是有向无环图,根据原始做法是反图topsort出解,编号小的说明顺序在后,选择这个点符合定义. #include<cstdio ...

  5. LA 4328 Priest John's Busiest Day (Greedy)

    https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...

  6. POJ - 3683 Priest John's Busiest Day(2-SAT+路径打印)

    题目链接:点击查看 题目大意:现在有n对新人要结婚,每一场婚礼都要请牧师主持一个特殊的仪式,这个仪式必须在婚礼的前d分钟或者最后d分钟进行,现在问能否有一种安排,能让牧师参加到每一场婚礼去主持仪式,输 ...

  7. POJ 3683 Priest John's Busiest Day(2-ST)

    题目链接:http://poj.org/problem?id=3683 题意:有n个婚礼要举行,但是只有一个牧师.第i个婚礼使用牧师的时间长为leni,可以在开始时或结束时使用.问能否使得n个婚礼均举 ...

  8. pku 3683 Priest John's Busiest Day 2-sat判断有误解+输出可行解

    http://poj.org/problem?id=3683 题意: 一个教父,在一天中要给n对新婚夫妇举行婚礼.已知每对夫妇举行婚礼的起始时间Si和终止时间Ti ,教父送祝福的时间要么在Si-> ...

  9. POJ 3683 Priest John's Busiest Day (算竞进阶习题)

    2-SAT 可以把每一次仪式看成变量,0/1的取值分别为开头举行和结尾举行. 转换为2-SAT接受的命题,就是看某一次仪式中有没有重合的时间段,有的话,就按照不冲突的形式连有向边. 然后跑tarjan ...

  10. POJ 3683 Priest John's Busiest Day

    2-SAT简单题,判断一下两个开区间是否相交 #include<cstdio> #include<cstring> #include<cmath> #include ...

最新文章

  1. 二次元萌妹在电车上顺拐啾咪为哪般?
  2. android弹出选择usb,android 解决:默认情况下用于该USB设备 自动获取USB操作权限...
  3. 单片机用python还是c语言_单片机为什么一直用C语言,不用其他编程语言?
  4. 2018年4月1日 蓝桥杯 C/C++B组答案 明码
  5. 使用Junit参数在更短的时间内编写更好的单元测试
  6. “约见”面试官系列之常见面试题之第四十八篇之各个浏览器内核(建议收藏)
  7. db2电话号码加密脚本
  8. 南京大学杨杨计算机,国际交流,研途有术 | 博士生国际学术交流经验分享会(四)...
  9. 猪肉种类,全国“名猪”大盘点
  10. 夜神模拟器ADB版本不一致问题
  11. 使用计算机眼睛保护方法有哪些,​计算机族的“护眼诀窍”
  12. 神经元的细胞体位于哪里,神经在人体的什么部位
  13. 程序员节你们公司都有什么活动
  14. name '__file__' is not defined
  15. 【openSSH】通过证书文件免密码远程登录
  16. 微信简史:2年时间从0到3亿的微创新
  17. 无线网络呗主服务器限制网速怎么办,怎么设置限制别人wifi网速,wifi限制网速设置多少...
  18. 制作游戏场景,必须掌握的软件有哪些?
  19. Java写文字冒险类游戏_用木兰语言编写文字冒险游戏(十三、四章),又一个特性发现...
  20. IPv6在企业网络中的应用

热门文章

  1. c语言中 输出操作是由库函数,【判断题】在 C语言中,输入操作是由库函数scanf完成,输出操作是由库函数printf完成 。...
  2. html风琴图片展示,基于jquery的手风琴图片展示效果实现方法
  3. CVPR 2019 论文最新汇总(按方向划分,0611 更新中)
  4. 最全电商分类信息(03)
  5. spyder数据分析
  6. CTF 实验吧 变异凯撒 writeup
  7. 【PMBOK重点知识】工作绩效数据、工作绩效信息、工作绩效报告之间的区别和关系
  8. apache-felix实例
  9. Browserslist: caniuse-lite is outdated. Please run: npx browserslist@latest --update-db
  10. 135、即时通讯简介