[题解]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 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相关推荐
- POJ 3683 Priest John's Busiest Day(2-ST)
题目链接:http://poj.org/problem?id=3683 题意:有n个婚礼要举行,但是只有一个牧师.第i个婚礼使用牧师的时间长为leni,可以在开始时或结束时使用.问能否使得n个婚礼均举 ...
- POJ - 3683 Priest John's Busiest Day(2-SAT+路径打印)
题目链接:点击查看 题目大意:现在有n对新人要结婚,每一场婚礼都要请牧师主持一个特殊的仪式,这个仪式必须在婚礼的前d分钟或者最后d分钟进行,现在问能否有一种安排,能让牧师参加到每一场婚礼去主持仪式,输 ...
- POJ 3683 Priest John's Busiest Day (算竞进阶习题)
2-SAT 可以把每一次仪式看成变量,0/1的取值分别为开头举行和结尾举行. 转换为2-SAT接受的命题,就是看某一次仪式中有没有重合的时间段,有的话,就按照不冲突的形式连有向边. 然后跑tarjan ...
- POJ 3683 Priest John's Busiest Day
2-SAT简单题,判断一下两个开区间是否相交 #include<cstdio> #include<cstring> #include<cmath> #include ...
- pku 3683 Priest John's Busiest Day 2-sat判断有误解+输出可行解
http://poj.org/problem?id=3683 题意: 一个教父,在一天中要给n对新婚夫妇举行婚礼.已知每对夫妇举行婚礼的起始时间Si和终止时间Ti ,教父送祝福的时间要么在Si-> ...
- poj3683 Priest John's Busiest Day
输出方案的2-sat 直接比较两个点强联通分量的编号,缩完点的图应该是有向无环图,根据原始做法是反图topsort出解,编号小的说明顺序在后,选择这个点符合定义. #include<cstdio ...
- LA 4328 Priest John's Busiest Day (Greedy)
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_probl ...
- 【2-SAT初学+模板题讲解】POJ3683 Priest John's Busiest Day
什么是2-SAT? SAT是适定性(Satisfiability)问题的简称 .一般形式为k-适定性问题,简称 k-SAT. 可以证明,当k>2时,k-SAT是NP完全的.因此一般讨论的是k=2 ...
- [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 ...
最新文章
- 深度神经网络混合精度训练
- 神经科学如何影响人工智能?看DeepMind在NeurIPS2020最新《神经科学人工智能》报告,126页ppt...
- EL表达式的11个内置对象
- 点乘和叉乘的区别_关于延时和混响的区别与专用延时器与混响器的调控技巧
- php将mysql转换为json字符串_在PHP中将MySQL记录集转换为JSON字符串
- 小D课堂 - 零基础入门SpringBoot2.X到实战_第三节SpringBoot热部署devtool和配置文件自动注入实战_16、注解配置文件自动映射到属性和实体类实战...
- java继承封装多态特性_java 三大特性 封装 继承 多态
- 如何改变证件照大小?三步搞定
- 数据质量管理十步流程
- 区块链技术应用在金融领域之大数据风控
- Android 定制关机界面
- python操作word详细操作_Python操作Word的入门教程
- 今日简报 每日精选12条新闻简报 每天一分钟 知晓天下事 4月24日
- 英语语法笔记——状语从句(五)
- 程序员怎么高效做笔记
- 怎么把视频里的音乐提取成音频?
- 搭建syslog服务器+log4j2输出日志到syslog
- 卸载windows服务,删除 windows 服务 delete windows service
- 插值算法(用于预测)
- internet协议服务器在哪,网络协议在哪设置
热门文章
- PyTorch基础(12)-- torch.nn.BatchNorm2d()方法
- UNIX再学习 -- XSI IPC通信方式
- python安装系统要求_python需要什么系统 | window重装系统教程
- 汇编语言LENGTHOF运算符:计算数组中元素的个数
- 从Tensorflow代码中理解LSTM网络
- Binder fuzz安全研究
- 数据库连接python_python连接数据库
- android 视频 截图,java – android获取当前视频的截图
- mysql 按时间累计计算_MySQL某公司面试题累计值的计算案例
- 基于深度学习的目标检测方法综述