【题解】Priest John's Busiest Day POJ - 3683 ⭐⭐⭐ 【2-SAT 拓扑序】
Priest John’s Busiest Day POJ - 3683
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.
Examples
Sample Input
2
08:00 09:00 30
08:15 09:00 20
Sample Output
YES
08:00 08:30
08:40 09:00
Hint
题意:
有n个婚礼,每个婚礼有起始时间si,结束时间ti,还有一个主持时间ti,ti必须安排在婚礼的开始或者结束,
主持由祭祀来做,但是只有一个祭祀,所以 各个婚礼的主持时间不能重复,问你有没有可能正常的安排主持时间,
不能输出no,能的话要输出具体的答案:即每个婚礼的主持时间段是什么样的。
题解:
转化为2-SAT问题来考虑, 每场婚礼分为开始和结束来考虑, 找出所有可能的冲突
对于婚礼i和婚礼j。i表示在开始主持,i2表示在结束主持,j类似。
枚举每一对不同的i和j。
如果i和j冲突。连接i j2
如果i和j2冲突,连接i j
如果i2和j冲突,连接i2 j2
如果i2和j2冲突,连接i2 j
接下来遍历1-N, 缩点后强连通分量拓扑序在前则开始时举行, 否则结束时举行, 有冲突则无法举行
经验小结:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <stdlib.h>
#include <vector>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const int inf = 1<<30;
const LL maxn = 1010*4;int N, M, ecnt, head[maxn];
struct node{int to, next;
}es[maxn*maxn];
void addEdge(int u, int v){es[ecnt].to = v, es[ecnt].next = head[u];head[u] = ecnt++;
}
int indx = 0, scc = 0;
bool ins[maxn];
int dfn[maxn], low[maxn], belong[maxn];
stack<int> stk;
void Tarjan(int u){int v;dfn[u] = low[u] = ++indx;stk.push(u);ins[u] = true;for(int i = head[u]; i != -1; i = es[i].next){int v = es[i].to;if(!dfn[v]){Tarjan(v);low[u] = min(low[u], low[v]);}else if(ins[v]){low[u] = min(low[u], dfn[v]);}}if(dfn[u] == low[u]){++scc;do{v = stk.top();stk.pop();ins[v] = false;belong[v] = scc;}while(u != v);}
}
bool solve(){for(int i = 0; i < N*2; ++i)if(!dfn[i])Tarjan(i);for(int i = 0; i < N; ++i)if(belong[i] == belong[i+N])return false;return true;
}
int s[maxn], e[maxn], d[maxn];
int main()
{ms(head, -1);int h1, m1, h2, m2;scanf("%d",&N);for(int i = 0; i < N; ++i){scanf("%d:%d %d:%d %d",&h1,&m1,&h2,&m2,&d[i]);s[i] = h1*60+m1, e[i] = h2*60+m2;}//i表示i在开始时, i+N表示i在结束时for(int i = 0; i < N; ++i){for(int j = 0; j < i; ++j){//i在开始时和j在开始时冲突if(min(s[i]+d[i], s[j]+d[j]) > max(s[i], s[j])){addEdge(i, N+j);addEdge(j, N+i);}//i在结束时和j在结束时冲突if(max(e[i]-d[i], e[j]-d[j]) < min(e[i], e[j])){addEdge(i+N, j);addEdge(j+N, i);}//i在结束时和j在开始时冲突if(max(e[i]-d[i], s[j]) < min(e[i], s[j]+d[j])){addEdge(i+N, j+N);addEdge(j, i);}//i在开始时和j在结束时冲突if(max(e[j]-d[j], s[i]) < min(e[j], s[i]+d[i])){addEdge(j+N, i+N);addEdge(i, j);}}}if(solve()){printf("YES\n");for(int i = 0; i < N; ++i){if(belong[i] < belong[N+i]) //开始的拓扑序在前, 则在开始时举行典礼printf("%02d:%02d %02d:%02d\n",s[i]/60,s[i]%60,(s[i]+d[i])/60,(s[i]+d[i])%60);elseprintf("%02d:%02d %02d:%02d\n",(e[i]-d[i])/60,(e[i]-d[i])%60,e[i]/60,e[i]%60);}}else printf("NO\n");return 0;
}
【题解】Priest John's Busiest Day POJ - 3683 ⭐⭐⭐ 【2-SAT 拓扑序】相关推荐
- [题解]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 ...
- 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 ...
最新文章
- YOLO项目复活!大神接过衣钵,YOLO之父隐退2月后,v4版正式发布,性能大幅提升...
- SAP SD信用控制管理
- 用grub4dos修复grub
- 如何搭建一个node 工程
- c/c++ 友元基本概念
- Linux系统编程:使用mutex互斥锁和条件变量实现多个生成者和消费者模型
- opencv qt5安装linux,Ubuntu OpenCV安装和设置(Qt5吗?)
- 冰原服务器维护,12月2日服务器公告 冰原旅途进发
- MySQL基础 — 常用命令
- SAP VA01 消息 没有用于售达方 XXXXXX 的客户主记录存在
- 网络模型早停earlystopping详解
- Windows系统备份
- dw中html是什么,dw中的css是什么意思?
- 机器学习PAI为你自动写歌词,妈妈再也不用担心我的freestyle了
- 元宇宙链游OAS即将正式上线,社区热度只增不减
- mkfs.ext3 --Discarding device blocks: 4096/196608
- python 游戏开发jumpy platform 终板
- pandas.tseries.offset, 获取季度,月度第一天(最后一天)
- 【数据处理】xml的创建、读写问题
- 如何搭建“业务化”的指标体系?
热门文章
- 高绩效团队-VUCA时代的五个管理策略《二》—代际管理
- 奈奎斯特定理和香农定理
- 对信息断舍离进行时——一段自我反省
- 怎么看两张图片的相似度,测试两张照片相似度
- 基于Java Servlet图片服务器
- 如何计算CAN总线的负载率以及每帧耗时和每秒最多传输帧数
- windows连接vpn无法连接网络解决
- 哈希表——线性探测法、链地址法、查找成功、查找不成功的平均长度
- 【Trailhead题目解析】Prepare your salesforce org for users - 5Create Chatter Groups
- C#实战004:Excel操作-读取Excel工作簿