#HK4263. 「KTSC 2024 R2」病毒
「KTSC 2024 R2」病毒
注意事项
在 LibreOJ 上,由于语言限制,目前只支持以下语言的提交:
- C++(标准为 C++ 17 及以上)
请在提交源代码前添加 #include "virus.h"。
题目描述
题目译自 2024년도 국제정보올림피아드 대표학생 선발고사 - 2차 선발고사 T4 「바이러스」
由于上次新冠疫情的严重影响,KOI 城市决定为未来可能发生的疫情做好充分准备。为此,KOI 城市希望分析当前城市结构对病毒的脆弱程度。
KOI 城市由 个地点和 条双向道路组成,任意两个不同的地点都可以通过这些道路互相到达。也就是说,城市的道路网络是一个树结构。每个地点用 到 的不同整数表示。由于城市的道路网络是树结构,对于任意两个地点 和 ,从 到 的唯一简单路径上的边数定义为 和 之间的距离。
KOI 城市有 名居民。对于每个 ,第 个人住在 号地点,并且可以到达距离 不超过 的地点。
KOI 城市的病毒学家们建立了一个模型来模拟病毒在两个人之间的传播过程。对于每个 ,第 号地点的传播时间用一个正整数 表示。假设第 个人在时间 首次感染病毒,并且第 个人从第 个人那里接收到病毒。如果存在一个地点 ,使得 号地点与 号地点的距离不超过 ,且 号地点与 号地点的距离不超过 ,那么 号地点就是传播的媒介。
如果没有这样的传播媒介,第 个人不会直接从第 个人那里感染病毒(当然,他可能通过其他人间接感染)。如果存在传播媒介,那么在所有可能的传播媒介中,选择传播时间最短的地点 。如果第 个人在时间 之前没有感染病毒,那么他将在时间 被第 个人感染。病毒以这种方式在所有不同的两个人之间传播。
在上述模型下,KOI 城市的研究人员希望计算当第 个人在时间 感染病毒时,其他人何时感染病毒。你需要计算对于每个 ,第 个人首次感染病毒的时间。如果第 个人没有感染病毒,则记录为 。
实现细节
你需要实现以下函数:
vector<long long> find_spread(int N, int M, vector<int> A, vector<int> B, vector<int> P, vector<int> D, vector<int> C);
N:KOI 城市的地点数量。M:KOI 城市的居民数量。A, B:长度为 的数组。对于每个 ,存在一条连接 和 的道路。每条道路在两个数组中只出现一次。P, D:长度为 的数组。对于每个 ,第 个人住在 号地点,并且可以到达距离 不超过 的地点。C:长度为 的数组。对于每个 ,第 号地点的传播时间为 。- 该函数返回一个长度为 的数组 。对于每个 ,如果第 个人感染病毒, 表示他首次感染病毒的时间;如果没有感染,则为 。
- 该函数在每个测试用例中只会被调用一次。
注意,提交的代码中不应包含任何输入输出操作。
样例 1
考虑 $N=8, M=5, A=[0,1,2,3,4,5,6], B=[1,2,3,4,5,6,7], P=[2,5,7,1,4], D=[2,0,0,1,1], C=[40,5,5,16,32,8,1,10]$ 的情况。
评测程序将调用如下函数:
find_spread(8, 5, [0,1,2,3,4,5,6], [1,2,3,4,5,6,7], [2,5,7,1,4], [2,0,0,1,1], [40,5,5,16,32,8,1,10]);
在这种情况下,病毒传播如下:
- 时间 ,第 个人感染。
- 时间 ,第 个人感染。第 个人从第 个人那里感染,传播媒介是 号地点( 号地点也可以作为传播媒介)。
- 时间 ,第 个人感染。第 个人从第 个人那里感染,传播媒介是 号地点。
- 时间 ,第 个人感染。第 个人从第 个人那里感染,传播媒介是 号地点。
- 第 个人始终未感染。
函数应返回 [0, 24, -1, 5, 16]。
样例 2
评测程序将调用如下函数:
find_spread(8, 5, [0,1,2,3,4,3,3], [1,2,3,4,5,6,7], [2,5,7,1,4], [2,0,0,1,1], [40,5,5,16,32,8,1,10]);
函数应返回 [0, 24, 10, 5, 16]。
样例 3
评测程序将调用如下函数:
find_spread(10, 10, [9,0,1,5,3,8,0,6,0], [3,6,8,1,2,7,4,5,9], [9,7,1,8,6,1,4,7,5,5], [0,2,0,1,3,2,6,2,1,4], [10,12,5,9,8,21,20,6,13,5]);
函数应返回 [0, 11, 17, 11, 5, 11, 5, 11, 17, 5]。
样例 4
评测程序将调用如下函数:
find_spread(1, 2, [], [], [0, 0], [0, 0], [1000000000]);
函数应返回 [0, 1000000000]。
数据范围与提示
对于所有输入数据,满足:
- 对于所有 ,
- 对于所有 ,
- 对于所有 ,
详细子任务附加限制及分值如下表所示。
| 子任务 | 分值 | 附加限制 |
|---|---|---|
| ; 对于所有 , |
||
| ; 对于所有 , |
||
| 对于所有 , | ||
| 无附加限制 |
示例评测程序
示例评测程序按以下格式读取输入:
- 第 行:
- 第 行:
- 第 行:
- 第 行:
示例评测程序按以下格式输出:
- 第 行:函数
find_spread返回的数组的第 个元素
注意,示例评测程序可能与实际评测程序不同。