题目

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.

输入格式

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.

输出格式

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.

输入样例

2

08:00 09:00 30

08:15 09:00 20

输出样例

YES

08:00 08:30

08:40 09:00

题解

2-sat + 输出方案

对于每一个婚礼,有两个时间段可以选择,对应两个点

对于每两个婚礼,如果其中两个时间段t1和t1'相交,那么这两个时间段冲突,连边t1->t2',t1'->t2

跑一遍tarjan缩点,若存在婚礼的两个时间段处于同一个强联通分量,则无解

否则输出方案:

QAQ蒟蒻知道有两种方法:

①拓扑排序

将缩完点后的图反向建边,按拓扑顺序访问,每访问到一个没有染色的点,就染为第一种颜色,并令其对应点【对称的那个强两桶分量缩的点】及对应点延伸出去能到达的所有点染另一种颜色【一次dfs】

②按Scc编号

很神奇的方法,所有点对中,输出Scc编号较小的那个即可。。。【比拓扑简单多了 → →】

证明【假的】:tarjan缩点时拓扑序大的先缩,则编号较小,然而我们需要选择拓扑序大的,因为拓扑大的不会推出拓扑序小的

选择一个喜欢方法就可以A了> <

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 2005,maxm = 2000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int n,m,h[maxn],ne = 1;
struct EDGE{int to,nxt;}ed[maxm];
inline void build(int u,int v){
ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;
}
int dfn[maxn],low[maxn],Scc[maxn],scci = 0,cnt = 0,st[maxn],top = 0;
void dfs(int u){
dfn[u] = low[u] = ++cnt;
st[++top] = u;
Redge(u)
if (!dfn[to = ed[k].to])
dfs(to),low[u] = min(low[u],low[to]);
else if (!Scc[to]) low[u] = min(low[u],dfn[to]);
if (dfn[u] == low[u]){
scci++;
do{
Scc[st[top]] = scci;
}while (st[top--] != u);
}
}
int B[maxn],T[maxn],ans[maxn],inde[maxn];
void print(int x){
printf("%02d:%02d ",x / 60,x % 60);
}
bool judge(int u,int v){
if (T[u] <= B[v] || B[u] >= T[v]) return false;
return true;
}
int main(){
n = read(); int a,b,t;
for (int i = 1; i <= n; i++){
a = read(); b = read(); B[2 * i - 1] = a * 60 + b;
a = read(); b = read(); T[2 * i] = a * 60 + b;
t = read();
T[2 * i - 1] = B[2 * i - 1] + t;
B[2 * i] = T[2 * i] - t;
}
for (int i = 1; i <= n; i++)
for (int j = i + 1; j <= n; j++){
if (judge(2 * i,2 * j))
build(2 * i,2 * j - 1),build(2 * j,2 * i - 1);
if (judge(2 * i,2 * j - 1))
build(2 * i,2 * j),build(2 * j - 1,2 * i - 1);
if (judge(2 * i - 1,2 * j))
build(2 * i - 1,2 * j - 1),build(2 * j,2 * i);
if (judge(2 * i - 1,2 * j - 1))
build(2 * i - 1,2 * j),build(2 * j - 1,2 * i);
}
for (int i = 1; i <= (n << 1); i++) if (!dfn[i]) dfs(i);
bool flag = true;
for (int i = 1; i <= n; i++) if (Scc[2 * i] == Scc[2 * i - 1]){
flag = false; break;
}
if (!flag) puts("NO");
else {
puts("YES");
for (int i = 1; i <= n; i++)
if (Scc[2 * i] < Scc[2 * i - 1])
print(B[2 * i]),print(T[2 * i]),puts("");
else print(B[2 * i - 1]),print(T[2 * i - 1]),puts("");
}
return 0;
}

POJ3683 Priest John's Busiest Day 【2-sat】的更多相关文章

  1. POJ3683 Priest John's Busiest Day(2-SAT)

    Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 11049   Accepted: 3767   Special Judge ...

  2. poj3683 Priest John's Busiest Day

    2-SAT 输出可行解 找可行解的方案就是: 根据第一次建的图建一个反图..然后求逆拓扑排序,建反图的原因是保持冲突的两个事件肯定会被染成不同的颜色 求逆拓扑排序的原因也是为了对图染的色不会发生冲突, ...

  3. poj3683 Priest John's Busiest Day

    2-SAT. 读入用了黄学长的快速读入,在此膜拜感谢. 把每对时间当作俩个点.如果有交叉代表相互矛盾. 然后tarjan缩点,这样就能得出当前的2-SAT问题是否有解. 如果有解,跑拓扑排序就能找出一 ...

  4. POJ 3683 Priest John's Busiest Day 【2-Sat】

    这是一道裸的2-Sat,只要考虑矛盾条件的判断就好了. 矛盾判断: 对于婚礼现场 x 和 y,x 的第一段可以和 y 的第一段或者第二段矛盾,同理,x 的第二段可以和 y 的第一段或者第二段矛盾,条件 ...

  5. poj 3683 Priest John's Busiest Day【2-SAT+tarjan+拓扑】

    转换成2-SAT模型,建边是如果时间(i,j)冲突就连边(i,j'),其他同理 tarjan缩点,判可行性 返图拓扑,输出方案 #include<iostream> #include< ...

  6. UVA1420 Priest John's Busiest Day【贪心】

    题意简介 有一个司仪,要主持n场婚礼,给出婚礼的起始时间和终止时间,每个婚礼需要超过一半的时间做为仪式,并且仪式不能终止.问说司仪能否主持n场婚礼. 输入格式 多组数据,每组数据输入一个\(N\)(\ ...

  7. 【POJ3683】Priest John's Busiest Day

    题目 John is the only priest in his town. September 1st is the John's busiest day in a year because th ...

  8. 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 ...

  9. 图论(2-sat):Priest John's Busiest Day

    Priest John's Busiest Day   Description John is the only priest in his town. September 1st is the Jo ...

随机推荐

  1. perl 输出当前时间

    #!/bin/perluse POSIX;print strftime("%Y-%m-%d %H:%M:%S", localtime);

  2. 题解 P1319 【压缩技术】

    这题是红题,我都觉得我的题解过不了 这道题输入不像别的题,给一个参数 n ,然后输入 n 的倍数个数据,它是给一个 n , 再输入一堆数.看题目,n × n ? 是不是就说明了给出的数和一定,都是 n ...

  3. CUDA:Supercomputing for the Masses (用于大量数据的超级计算)-第八节

    原文链接 第八节:利用CUDA函数库 Rob Farber 是西北太平洋国家实验室(Pacific Northwest National Laboratory)的高级科研人员.他在多个国家级的实验室进 ...

  4. RPC - 麻雀虽小,五脏俱全

    说起 RPC (远程过程调用),大家应该不陌生.随着微服务.分布式越来越流行,RPC 应用越来越普遍.常见的 RPC 框架如:Dubbo.gRPC.Thrift 等.本篇文章不是介绍各种 RPC 的使 ...

  5. 对mysql快速批量修改,查重

    更新UPDATE mytable SET myfield = CASE id WHEN 1 THEN 'value' WHEN 2 THEN 'value' WHEN 3 THEN 'value' E ...

  6. c语言中--typeof--关键字用法

    C语言中 typeof 关键字是用来定义变量数据类型的.在linux内核源代码中广泛使用. 下面是Linux内核源代码中一个关于typeof实例: #define min(x, y) ({ \ typ ...

  7. 绘制弧形:imagearc() 说明:三点钟的位置是起点(0度

    <?php //1. 绘制图像资源(创建一个画布) $image = imagecreatetruecolor(500, 300); //2. 先分配一个绿色 $green = imagecol ...

  8. Python基础:条件与循环

    条件语句 除了 boolean 类型的数据,条件判断最好是显性的 if i != 0: ... 而不是只写出变量名: if i: ... For循环与While循环 通常来说,如果你只是遍历一个已知的 ...

  9. 内存管理小结(2)--伙伴系统API

    伙伴系统分配内存以2的整数幂次的页数为单位.提供的API主要分为分配类与释放类. 1.分配类 1.1unsigned long __get_free_pages(gfp_t gfp_mask, uns ...

  10. request_resource

    1.全局变量 resource结构体定义如下,指针parent.sibling.child用于构建树状结构. struct resource { resource_size_t start; reso ...