【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).
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
---------------------------------------------------------------------------------------------------------------------------------

【题目大意】
有n场婚礼,每场婚礼有对应的开始和结束时间,每场婚礼都需要举行一场仪式,仪式持续时间为Di。仪式可以在婚礼前举行[Si,Si+Di],或者在婚礼后举行[Ti-Di,Ti]。要求每个婚礼的仪式不冲突,求一组仪式时间安排的可行解。
【题解】
裸的2-SAT问题。主要是建图,注意判断哪些方案会出现矛盾。其它为2-SAT的基础代码。
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 using namespace std;
  6 #define MAXN 1020*2
  7 int n;
  8 struct Thing
  9 {
 10     int st,ed,Len;
 11 }p[MAXN];
 12 struct node
 13 {
 14     int v;
 15     node *next;
 16 };
 17 node edge[MAXN*MAXN];
 18 node *cnt=&edge[0];
 19 node *adj[MAXN];
 20 node edge2[MAXN*MAXN];
 21 node *cnt2=&edge2[0];
 22 node *adj2[MAXN];
 23 int dfn[MAXN],low[MAXN],dcnt;
 24 int Belong[MAXN],Num[MAXN];
 25 int stack[MAXN],top;
 26 int In[MAXN],opp[MAXN],scc;
 27 int q[MAXN],col[MAXN];
 28 bool Instack[MAXN],ans[MAXN];
 29 char s1[10],s2[10];
 30 inline void Addedge(int u,int v)
 31 {
 32     node *p=++cnt;
 33     p->v=v;
 34     p->next=adj[u];
 35     adj[u]=p;
 36 }
 37 inline void Addedge2(int u,int v)
 38 {
 39     node *p=++cnt2;
 40     p->v=v;
 41     p->next=adj2[u];
 42     adj2[u]=p;
 43 }
 44 inline int Cal(char str[])
 45 {
 46     int Ret=((str[0]-'0')*10+str[1]-'0')*60+(str[3]-'0')*10+str[4]-'0';
 47     return Ret;
 48 }
 49 inline bool Check(int st1,int len1,int st2,int len2)
 50 {
 51     return (st2<st1+len1)&&(st1<st2+len2);
 52 }
 53 void Read()
 54 {
 55     //scanf("%d",&n);
 56     int i;
 57     for(i=1;i<=n;i++)
 58     {
 59         scanf("%s%s%d",s1,s2,&p[i].Len);
 60         p[i].st=Cal(s1);
 61         p[i].ed=Cal(s2);
 62     }
 63 }
 64 void Build_map()
 65 {
 66     int i,j;
 67     for(i=1;i<=n;i++)
 68         for(j=1;j<=n;j++)
 69         {
 70             if(i==j)
 71                 continue;
 72             if(Check(p[i].st,p[i].Len,p[j].st,p[j].Len))
 73                 Addedge(i,j+n);
 74             if(Check(p[i].st,p[i].Len,p[j].ed-p[j].Len,p[j].Len))
 75                 Addedge(i,j);
 76             if(Check(p[i].ed-p[i].Len,p[i].Len,p[j].st,p[j].Len))
 77                 Addedge(i+n,j+n);
 78             if(Check(p[i].ed-p[i].Len,p[i].Len,p[j].ed-p[j].Len,p[j].Len))
 79                 Addedge(i+n,j);
 80         }
 81 }
 82 void Tarjan(int u)
 83 {
 84     int v;
 85     dfn[u]=low[u]=++dcnt;
 86     stack[++top]=u;
 87     Instack[u]=true;
 88     for(node *p=adj[u];p;p=p->next)
 89     {
 90         v=p->v;
 91         if(!dfn[v])
 92         {
 93             Tarjan(v);
 94             low[u]=min(low[u],low[v]);
 95         }
 96         else if(Instack[v])
 97             low[u]=min(low[u],dfn[v]);
 98     }
 99     if(dfn[u]==low[u])
100     {
101         scc++;
102         do
103         {
104             v=stack[top];
105             top--;
106             Instack[v]=false;
107             Belong[v]=scc;
108             Num[scc]++;
109         }while(v!=u);
110     }
111 }
112 bool Work()
113 {
114     int i;
115     for(i=1;i<=n*2;i++)
116         if(!dfn[i])
117             Tarjan(i);
118     for(i=1;i<=n;i++)
119     {
120         if(Belong[i]==Belong[i+n])
121             return false;
122         opp[Belong[i]]=Belong[i+n];
123         opp[Belong[i+n]]=Belong[i];
124     }
125     int u,v;
126     for(i=1;i<=n*2;i++)
127         for(node *p=adj[i];p;p=p->next)
128         {
129             v=p->v;
130             if(Belong[i]!=Belong[v])
131             {
132                 Addedge2(Belong[v],Belong[i]);
133                 In[Belong[i]]++;
134             }
135         }
136     int l=0,r=0;
137     for(i=1;i<=scc;i++)
138         if(!In[i])
139         {
140             q[r]=i;
141             r++;
142         }
143     while(l<r)
144     {
145         u=q[l];
146         l++;
147         if(!col[u])
148         {
149             col[u]=1;
150             col[opp[u]]=-1;
151         }
152         for(node *p=adj2[u];p;p=p->next)
153         {
154             v=p->v;
155             In[v]--;
156             if(!In[v])
157             {
158                 q[r]=v;
159                 r++;
160             }
161         }
162     }
163     for(i=1;i<=n;i++)
164         if(col[Belong[i]]==1)
165             ans[i]=true;
166     return true;
167 }
168 void Print()
169 {
170     if(Work())
171     {
172         printf("YES\n");
173         int i;
174         for(i=1;i<=n;i++)
175         {
176             if(ans[i])
177                 printf("%02d:%02d %02d:%02d\n",p[i].st/60,p[i].st%60,(p[i].st+p[i].Len)/60,(p[i].st+p[i].Len)%60);
178             else
179                 printf("%02d:%02d %02d:%02d\n",(p[i].ed-p[i].Len)/60,(p[i].ed-p[i].Len)%60,p[i].ed/60,p[i].ed%60);
180         }
181     }
182     else
183         printf("NO\n");
184 }
185 inline void Pre()
186 {
187     memset(edge,0,sizeof(edge));
188     memset(adj,0,sizeof(adj));
189     cnt=&edge[0];
190     memset(edge2,0,sizeof(edge2));
191     memset(adj2,0,sizeof(adj2));
192     cnt2=&edge2[0];
193     memset(dfn,0,sizeof(dfn));
194     memset(low,0,sizeof(low));
195     dcnt=0;
196     top=0;
197     memset(Instack,false,sizeof(Instack));
198     memset(Belong,0,sizeof(Belong));
199     memset(Num,0,sizeof(Num));
200     scc=0;
201     memset(opp,0,sizeof(opp));
202     memset(In,0,sizeof(In));
203     memset(q,0,sizeof(q));
204     memset(col,0,sizeof(col));
205     memset(ans,false,sizeof(ans));
206 }
207 int main()
208 {
209     //freopen("Data.in","r",stdin);
210     //freopen("Data.out","w",stdout);
211     while(scanf("%d",&n)!=EOF)
212     {
213         Pre();
214         Read();
215         Build_map();
216         Print();
217     }
218     return 0;
219 }

转载于:https://www.cnblogs.com/CQBZOIer-zyy/archive/2013/01/22/2872211.html

[题解]POJ 3683 Priest John's Busiest Day相关推荐

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

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

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

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

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

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

  4. POJ 3683 Priest John's Busiest Day

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

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

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

  6. poj3683 Priest John's Busiest Day

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

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

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

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

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

  9. [2-sat专练]poj 3683,hdu 1814,hdu 1824,hdu 3622,hdu 4115,hdu 4421

    文章目录 Priest John's Busiest Day code Peaceful Commission code Let's go home code Bomb Game code Elimi ...

最新文章

  1. 深度神经网络混合精度训练
  2. 神经科学如何影响人工智能?看DeepMind在NeurIPS2020最新《神经科学人工智能》报告,126页ppt...
  3. EL表达式的11个内置对象
  4. 点乘和叉乘的区别_关于延时和混响的区别与专用延时器与混响器的调控技巧
  5. php将mysql转换为json字符串_在PHP中将MySQL记录集转换为JSON字符串
  6. 小D课堂 - 零基础入门SpringBoot2.X到实战_第三节SpringBoot热部署devtool和配置文件自动注入实战_16、注解配置文件自动映射到属性和实体类实战...
  7. java继承封装多态特性_java 三大特性 封装 继承 多态
  8. 如何改变证件照大小?三步搞定
  9. 数据质量管理十步流程
  10. 区块链技术应用在金融领域之大数据风控
  11. Android 定制关机界面
  12. python操作word详细操作_Python操作Word的入门教程
  13. 今日简报 每日精选12条新闻简报 每天一分钟 知晓天下事 4月24日
  14. 英语语法笔记——状语从句(五)
  15. 程序员怎么高效做笔记
  16. 怎么把视频里的音乐提取成音频?
  17. 搭建syslog服务器+log4j2输出日志到syslog
  18. 卸载windows服务,删除 windows 服务 delete windows service
  19. 插值算法(用于预测)
  20. internet协议服务器在哪,网络协议在哪设置

热门文章

  1. PyTorch基础(12)-- torch.nn.BatchNorm2d()方法
  2. UNIX再学习 -- XSI IPC通信方式
  3. python安装系统要求_python需要什么系统 | window重装系统教程
  4. 汇编语言LENGTHOF运算符:计算数组中元素的个数
  5. 从Tensorflow代码中理解LSTM网络
  6. Binder fuzz安全研究
  7. 数据库连接python_python连接数据库
  8. android 视频 截图,java – android获取当前视频的截图
  9. mysql 按时间累计计算_MySQL某公司面试题累计值的计算案例
  10. 基于深度学习的目标检测方法综述