371. 牧师约翰最忙碌的一天(tarjan,2-SAT)

371. 牧师约翰最忙碌的一天 - AcWing题库

牧师约翰在 9 月 1 日这天非常的忙碌。

有 N 对情侣在这天准备结婚,每对情侣都预先计划好了婚礼举办的时间,其中第 i 对情侣的婚礼从时刻 Si 开始,到时刻 Ti 结束。

婚礼有一个必须的仪式:站在牧师面前聆听上帝的祝福。

这个仪式要么在婚礼开始时举行,要么在结束时举行。

第 i 对情侣需要 Di 分钟完成这个仪式,即必须选择 Si∼Si+Di 或 Ti−Di∼Ti 两个时间段之一。

牧师想知道他能否满足每场婚礼的要求,即给每对情侣安排Si∼Si+Di 或 Ti−Di∼Ti,使得这些仪式的时间段不重叠。

若能满足,还需要帮牧师求出任意一种具体方案。

注意,约翰不能同时主持两场婚礼,且 所有婚礼的仪式均发生在 9 月 1 日当天

如果一场仪式的结束时间与另一场仪式的开始时间相同,则不算重叠。

例如:一场仪式安排在 08:00∼09:00,另一场仪式安排在 09:00∼10:00,则不认为两场仪式出现重叠。

输入格式

第一行包含整数 N。

接下来 N 行,每行包含 Si,Ti,Di,其中 Si 和 Ti 是 hh:mm 形式。

输出格式

第一行输出能否满足,能则输出 YES,否则输出 NO

接下来 N 行,每行给出一个具体时间段安排。

数据范围

1≤N≤1000

输入样例:
2
08:00 09:00 30
08:15 09:00 20
输出样例:
YES
08:00 08:30
08:40 09:00

解析: 

如果我们将每场婚礼看作是一个变量,那么每个变量就会有 开始时举办仪式 和 结束时举办仪式 两种取值,那么就启发我们可以用 2-SAT 来求解。将两种取值分别记为 x[i][0] 和 x[i][1],并看作节点 i 和 i + N

枚举每两场婚礼 i, j,若婚礼 i 的 x[i][p] 时间段与婚礼 j 的 x[j][q] 时间段重叠,则说明两者不能同时
被选为最终赋值。转化成 2-SAT 的形式,应该连 (i + p * N, j + (1 - q) * N) 和 (j + q * N, i + (1 - p) * N)两条有向边,两者互为逆否命题。

用 Tarjan 算法求强联通分量,检查是否存在 i 和 i + N 在同一个强连通分量即可。本题还需要输出方案。

这里给出 2-SAT 合法方案的两种构造方法。

第一种构造方法

首先,在一个强连通分量中,只要确定了一个变量的赋值,该强连通分量内其他变量的赋值也就直接确定了,
这启发我们考虑缩点,其次,因为互为逆否命题的有向边在图中成对出现,所以一个零出度点对面的点一定有出边。
选择一个有出边的店会使得该边指向的点必须也被选择,而选择一个零出度点则不会对其他任何点造出影响。

根据上述讨论,第一种构造方法的基本思想就是:自底向上执行拓扑排序,不断尝试选择零出度点。

1. 把强连通分量缩点,因为一般的拓扑排序是自顶向下根据入度进行的,所以我们建立一张缩点后的反图,具体来说:
    (1) 图上每个点都对应原图的强连通分量
    (2) 原图中的边 (x, y) 转化为新图中的边 (c[y], c[x]),其中 c[x] != c[y],c[x] 表示节点 x 所在的强连通分量
    (3) 对于原图中每个点 x,c[x] 和 c[x + N] 新图中两个对称的节点。
2. 在上述反图上统计每个点的入度,执行拓扑排序

    设val[k] 表示原图 k 号强连通分量的赋值标记,初始值为 -1

    从队头每取出一个节点 k (k 相当于原图中一个强连通分量的编号),就检查 k 的赋值标记,若 val[k] = -1 (尚未确定赋值),
    就令 val[k] = 0, val[k + N] = 1,随后把它能到达的点的入度减 1 (拓扑排序的正常过程)

3. 拓扑排序结束之后,就得到最终的答案,对于原图每个节点 i:
    若 val[c[i]] = 0,则变量 x[i] 应赋值为 x[i][0]
    若 val[c[i]] = 1,则变量 x[i] 应赋值为 x[i][1]

第二种构造方法

第二种构造方法是基于第一种构造方法的基础上,进一步利用了 Tarjan 算法对强连通分量编号的特殊性质,使得构造过程更简洁。
可以发现 Tarjan 算法的本质是一次 dfs,它在回溯时会先取出有向图底部的强连通分量进行标记,所以 Tarjan 算法得到的强连
通分量编号本身就已经满足缩点后有向无环图中自底向上的顺序,序列 1, 2, ..., cnt 就是缩点后的反图的拓扑序,无需进行拓
扑排序。

因此,直接比较节点所在的强连通分量的编号大小,即可确定对应变量的赋值 val[i],c[i] 和 c[i + N] 哪个小,就表示哪个会
先被遍历到,先被遍历到的是取值为 0,后被遍历到的取值为 1。

最终,同样的枚举一遍所有节点,根据 val[i] 来确定每个节点的值。

注:构造方法2 其实等于是 构造方法1 的升级版

作者:小小_88
链接:https://www.acwing.com/solution/content/112932/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 2e3 + 10, M = 4e6 + 10, INF = 0x3f3f3f3f;
int n, m;
int h[N], e[M], ne[M], idx;
int dfn[N], low[N], ts;
int id[N], cnt;
int stk[N], top;
bool in_stk[N];
struct we {int S, T, D;
}W[N];void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}bool is_overlap(int a, int b, int c, int d) {if (b <= c || d <= a)return 0;return 1;
}void tarjan(int u) {dfn[u] = low[u] = ++ts;stk[++top]=u, in_stk[u] = 1;for (int i = h[u]; i != -1; i = ne[i]) {int j = e[i];if (!dfn[j]) {tarjan(j);low[u] = min(low[u], low[j]);}else if (in_stk[j])low[u] = min(low[u], dfn[j]);}if (dfn[u] == low[u]) {int y;cnt++;do {y = stk[top--];id[y] = cnt;in_stk[y] = 0;} while (y != u);}
}int main() {cin >> n;memset(h, -1, sizeof h);for (int i = 0,s,ss,t,tt,d; i < n; i++) {scanf("%d:%d %d:%d %d", &s, &ss, &t, &tt, &d);W[i] = { s * 60 + ss,t * 60 + tt,d };}for (int i = 0; i < n; i++) {for (int j = 0; j < i; j++) {auto a = W[i], b = W[j];if (is_overlap(a.S, a.S + a.D, b.S, b.S + b.D))add(i, j + n), add(j, i + n);if (is_overlap(a.S, a.S + a.D, b.T - b.D, b.T))add(i, j), add(j + n, i + n);if (is_overlap(a.T - a.D, a.T, b.S, b.S + b.D))add(i + n, j + n), add(j, i);if (is_overlap(a.T - a.D, a.T, b.T - b.D, b.T))add(i + n, j), add(j + n, i);}}for (int i = 0; i < 2 * n; i++) {if (!dfn[i]) {tarjan(i);}}for (int i = 0; i < n; i++) {if (id[i] == id[i + n]) {cout << "NO" << endl;return 0;}}cout << "YES" << endl;for (int i = 0; i < n; i++) {int s = W[i].S, t = W[i].T, d = W[i].D;if (id[i] < id[i + n])printf("%02d:%02d %02d:%02d\n", (s) / 60, (s) % 60, (s + d) / 60, (s + d) % 60);elseprintf("%02d:%02d %02d:%02d\n", (t-d) / 60, (t-d) % 60, (t) / 60, (t) % 60);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/730228.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024 AI 辅助研发的新纪年

随着人工智能技术的持续发展与突破&#xff0c;2024年AI辅助研发正成为科技界和工业界瞩目的焦点。从医药研发到汽车设计&#xff0c;从软件开发到材料科学&#xff0c;AI正逐渐渗透到研发的各个环节&#xff0c;变革着传统的研发模式。在这一背景下&#xff0c;AI辅助研发不仅…

【Python】约瑟夫环问题

任务描述 据说著名历史学家 Josephus有过以下的故事&#xff1a;Josephus及他的朋友共41人围成一个圆圈&#xff0c;由第1个人开始报数&#xff0c;每数到3该人就必须出去&#xff0c;然后再由下一个人重新报数&#xff0c;直到圆圈上少于3人为止。Josephus 将朋友与自己安排在…

【kubernetes】关于k8s集群中的ingress规则案例

目录 一、k8s 对外服务之 Ingress 1.1什么是ingress 1.2外部的应用能够访问集群内的服务有哪些方案&#xff1f; 1.3Ingress 组成 1.4Ingress-Nginx 工作原理 1.5ingress 暴露服务的方式 二、实操ingress暴露服务 前期.部署 nginx-ingress-controller 2.1基于host网络…

RabbitMQ的Windows版安装教程

文章目录 前言一、Windows安装RabbitMQ总结 前言 曾经写过一篇关于RabbitMQ的Ubuntu安装教程&#xff08;http://t.csdnimg.cn/5CYfC&#xff09;&#xff0c;当时使用的是Docker将RabbitMQ安装到虚拟机上&#xff0c;但是有很多小伙伴问Windows上如何进行安装RabbitMQ&#x…

flink重温笔记(十二): flink 高级特性和新特性(1)——End-to-End Exactly-Once(端到端精确一致性语义)

Flink学习笔记 前言&#xff1a;今天是学习 flink 的第 12 天啦&#xff01;学习了 flink 高级特性和新特性之 End-to-End Exactly-Once&#xff08;端到端精确一致性语义&#xff09;&#xff0c;主要是解决大数据领域数据从数据源到数据落点的一致性&#xff0c;不会容易造成…

官宣!百度智能云千帆产品发布会3月21日北京见!

回望2023大模型狂奔的一年&#xff0c;百度智能云千帆大模型平台无疑是浓墨重彩的一笔。自2023年3月27日正式问世后&#xff0c;百度智能云千帆大模型平台以突飞猛进的速度持续发展。从模型、应用到生态&#xff0c;“千帆”书写着自身在大模型时代的答卷。 作为全球首个一站式…

web开发踩坑记

问题&#xff1a;npm install 在纯ipv6环境先无法安装包 现象&#xff1a; ping -6 registry.npmjs.org 是通的&#xff0c;说明可以解析到ipv6地址 解决方法&#xff1a; 在hosts文件中强制添加 registry.npmjs.org 解析到IPV6地址的记录 原因分析&#xff1a; 怀疑是npm的bug…

指针的学习5

目录 sizeof和strlen的区别 sizeof strlen 数组和指针笔试题解析 一维数组 字符数组 二维数组 指针运算笔试题解析 题目1&#xff1a; 题目2&#xff1a; 题目3&#xff1a; 题目4&#xff1a; 题目5&#xff1a; 题目6&#xff1a; 题目7&#xff1a; sizeof和…

Jmeter二次开发实现rsa加密

jmeter函数助手提供了大量的函数&#xff0c;像 counter、digest、random、split、strLen&#xff0c;这些函数在接口测试、性能测试中大量被使用&#xff0c;但是大家在实际工作&#xff0c;形形色色的测试需求不同&#xff0c;导致jmeter自带或者扩展插件给我们提供的函数无法…

MySQL GTID 简介 原理 应用场景 优点 注意事项

GTID&#xff08;Global Transaction Identifier&#xff09;是MySQL数据库中用于唯一标识事务的一种机制。GTID的引入旨在简化复制和故障恢复过程&#xff0c;确保数据一致性。在分布式系统和数据库复制中&#xff0c;GTID提供了一种跨多个数据库实例跟踪事务的方法。 GTID的…

vue3没有this怎么办?

在vue3中,新的组合式API中没有this,那我们如果需要用到this怎么办? 解决方法: getCurrentInstance 方法获取当前组件的实例&#xff0c;然后通过 ctx 或 proxy 属性获得当前上下文&#xff0c;这样我们就能在setup中使用router和vuex了 import { getCurrentInstance } from …

【无标题】linux 命令不生效,卡死

内核直接重启&#xff0c;不需要读取硬盘 [rootlocalhost opt]# ll-bash: /usr/bin/ls: Input/output error 解决方法 [rootlocalhost ~]# echo 1 > /proc/sys/kernel/sysrq [rootlocalhost opt]# echo b > /proc/sysrq-trigger

Redis中的SCAN渐进式扫描底层原理

Scan渐进式扫描原理 概述 由于Redis是单线程再处理用户的命令&#xff0c;而Keys命令会一次性遍历所有key&#xff0c;于是在命令执行过程中&#xff0c;无法执行其他命令。这就导致如果Redis中的key比较多&#xff0c;那么Keys命令执行时间就会比较长&#xff0c;从而阻塞Re…

代码随想录三刷 day17 | 二叉树之110.平衡二叉树 257. 二叉树的所有路径 404.左叶子之和

三刷day17 110.平衡二叉树257. 二叉树的所有路径404.左叶子之和 110.平衡二叉树 题目链接 解题思路&#xff1a; 求高度用后续遍历&#xff0c;先得到左子树和右子树的情况&#xff0c;然后再进行判断&#xff08;左右中&#xff09;使用递归遍历 代码如下&#xff1a; class…

即插即用篇 | YOLOv8 引入 ParNetAttention 注意力机制 | 《NON-DEEP NETWORKS》

论文名称:《NON-DEEP NETWORKS》 论文地址:https://arxiv.org/pdf/2110.07641.pdf 代码地址:https://github.com/imankgoyal/NonDeepNetworks 文章目录 1 原理2 源代码3 添加方式4 模型 yaml 文件template-backbone.yamltemplate-small.yamltemplate-large.yaml

程序员常用的几种算法

程序员常用的几种算法 一、程序员算法汇总二、程序员常用的几种算法1.选择排序算法1.1 选择排序算法解析&#xff1a;1.2 示例代码&#xff1a; 2.插入排序算法2.1 插入排序算法解析&#xff1a;2.2 示例代码&#xff1a; 3.冒泡排序算法3.1 冒泡排序算法解析&#xff1a;3.2 示…

LeetCode买卖股票的最佳时机

文章目录 LeetCode买卖股票的最佳时机121 买卖股票的最佳时机Ⅰ题目描述代码 122 买卖股票的最佳时间Ⅱ题目描述代码 123 买卖股票的最佳时机Ⅲ题目描述代码一&#xff08;会超时&#xff09;代码二&#xff08;dp&#xff09; 188 买卖股票的最佳时机Ⅳ题目描述代码 LeetCode买…

题记(51)--L1-023 输出GPLT

目录 一、题目内容 二、输入描述 三、输出描述 四、输入输出示例 五、完整C语言代码 一、题目内容 给定一个长度不超过10000的、仅由英文字母构成的字符串。请将字符重新调整顺序&#xff0c;按GPLTGPLT....这样的顺序输出&#xff0c;并忽略其它字符。当然&#xff0c;四…

【PyTorch】进阶学习:探索BCEWithLogitsLoss的正确使用---二元分类问题中的logits与标签形状问题

【PyTorch】进阶学习&#xff1a;探索BCEWithLogitsLoss的正确使用—二元分类问题中的logits与标签形状问题 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、Py…

微服务架构 | 多级缓存

INDEX 通用设计概述2 优势3 最佳实践 通用设计概述 通用设计思路如下图 内容分发网络&#xff08;CDN&#xff09; 可以理解为一些服务器的副本&#xff0c;这些副本服务器可以广泛的部署在服务器提供服务的区域内&#xff0c;并存有服务器中的一些数据。 用户访问原始服务器…