#HK4988. 「POI 2024/2025 R3」Redukcja połączeń

「POI 2024/2025 R3」Redukcja połączeń

注意事项

由于 IO 效率等问题,在 LibreOJ 上暂不支持标准输入输出交互。

题目描述

题目译自 XXXII Olimpiada Informatyczna – III etap Redukcja połączeń

Bajtocy 刚刚荣升为 Bajtocja 的首席建筑师。Bajtocja 由 nn (1n200000)(1 \leq n \leq 200000) 座城市组成,通过 mm (1m300000)(1 \leq m \leq 300000) 条双向道路连接,每条道路有唯一的正整数维护成本。城市编号从 00n1n-1,道路编号从 00m1m-1。道路网络保证任意两城可达,维护成本互不相同,每对城市最多由一条道路连接,且无道路连接同一城市。

新官上任的 Bajtocy 面临一项艰巨任务:国王 Bajtazar 要求关闭部分道路,同时确保任意两城仍可连通,以最小化剩余道路的维护成本总和。Bajtocy 需要确定哪些道路应保留。

然而,Bajtocy 并不知道各道路的具体维护成本,只能通过向顾问询问获取信息。询问分为两类:

  1. 独立型:比较两条无公共端点的道路成本。
  2. 星型:在一组共享同一端点的道路中,找出成本最低的道路。

你的任务是帮助 Bajtocy 使用这两种询问方式,确定应保留的道路集合。评分将根据两种询问的使用次数确定。

交互方式

本题为交互题,需编写程序通过询问确定结果。你可以选择使用提供的库或标准输入输出进行交互,但不可同时使用两者。选手文件提供两种交互方式的示例实现。程序不可打开任何文件,可使用标准错误输出(stderr),但需注意时间消耗。标准输出的冗余数据可能导致「Wrong Answer」。禁止故意干扰评测库的内部运行。注意:内存和时间限制仅针对你的程序,不包括交互器。

方式 1:使用库交互

在此方式下,程序不可使用标准输入输出。

C++

程序开头需包含:

#include "redlib.h"

库提供以下函数:

  • int DajN():返回城市数量 nn
  • std::vector<std::pair<int,int>> DajDrogi():返回 mm 个道路描述,每条道路为一个数对 (x,y)(x, y) (0x,y<n,xy)(0 \leq x, y < n, x \neq y),表示连接城市 xxyy。道路按返回顺序编号,成本互不相同。
  • int Niezalezne(int a, int b):比较无公共端点的道路 aabb (0a,b<m)(0 \leq a, b < m),若 aa 成本较低返回 1-1,若 bb 成本较低返回 11
  • int Gwiazda(std::vector<int> t):比较共享同一端点的道路集合 tt(包含道路编号),返回成本最低的道路编号。
  • void Wynik(std::vector<int> t):提交保留道路的编号集合,满足任务要求。调用后程序应终止。

Python

程序开头需包含:

from redlib import DajN, DajDrogi, Niezalezne, Gwiazda, Wynik

库提供以下函数:

  • DajN() -> int:返回城市数量 nn
  • DajDrogi() -> list[tuple[int, int]]:返回 mm 个道路描述,每条道路为元组 (x,y)(x, y) (0x,y<n,xy)(0 \leq x, y < n, x \neq y),表示连接城市 xxyy。道路按返回顺序编号,成本互不相同。
  • Niezalezne(a: int, b: int) -> int:比较无公共端点的道路 aabb (0a,b<m)(0 \leq a, b < m),若 aa 成本较低返回 1-1,若 bb 成本较低返回 11
  • Gwiazda(t: list[int]) -> int:比较共享同一端点的道路集合 tt,返回成本最低的道路编号。
  • Wynik(t: list[int]):提交保留道路的编号集合,满足任务要求。调用后程序应终止。

注意事项

以下情况将导致「Wrong Answer」:

  • 使用无效道路编号(不在 {0,1,,m1}\{0, 1, \ldots, m-1\} 内)。
  • Niezalezne 比较有公共端点的道路(包括同一道路)。
  • Gwiazda 比较无公共端点的道路集合或空集合。
  • Wynik 提交包含重复道路编号的集合。

方式 2:标准输入输出交互

第一行从标准输入读取两个整数 n,mn, m,分别表示城市数和道路数。
接下来的 mm 行,每行包含两个整数 x,yx, y (0x,y<n,xy)(0 \leq x, y < n, x \neq y),描述一条道路,连接城市 xxyy,按输入顺序编号,成本互不相同。

  • 独立型询问:输出一行,包含三个整数 1,a,b1, a, b (0a,b<m)(0 \leq a, b < m),比较无公共端点的道路 aabb。随后读取一个整数:1-1 表示 aa 成本较低,11 表示 bb 成本较低。
  • 星型询问:输出一行,包含 2,k2, kkk 个道路编号,比较共享同一端点的 kk 条道路。随后读取一个整数,表示成本最低的道路编号。
  • 提交结果:输出一行,包含 3,k3, kkk 个道路编号,表示保留的道路集合,满足任务要求。

以下情况将导致「Wrong Answer」:

  • 使用无效道路编号。
  • 独立型询问比较有公共端点的道路。
  • 星型询问使用无公共端点的道路集合或空集合。
  • 提交结果包含重复道路编号。

C++(流式输入输出)

包含头文件 <iostream>,输出每行使用 std::endl。单组提问示例:

std::cout << 1 << " " << a << " " << b << std::endl;
std::cin >> wynik;

C++(stdio 输入输出)

包含头文件 <cstdio>,输出每行调用 fflush(stdout)。单组提问示例:

printf("1 %d %d\n", a, b);
fflush(stdout);
scanf("%d", &wynik);

Python

输出每行设置 flush=True。单组提问示例:

print(f"1 {a} {b}", flush=True)
wynik = int(input())

示例评测程序

「文件」中提供了 C++ 和 Python 的示例(错误)解决方案,展示两种交互方式,以及样例(red0.in, red[1-3]ocen.in)、交互库和示例评测程序。测试用例格式为:

  • 第一行:整数 n,mn, m
  • 接下来的 mm 行:三个整数 xi,yi,wix_i, y_i, w_i,表示第 ii 条道路连接城市 xix_iyiy_i,成本为 wiw_i

方式 1:使用库交互

red.cppred.py 为基于库交互的示例(错误)解决方案。C++ 编译命令:

g++ -O3 -static -std=c++20 redlib.cpp red.cpp -o red.e

运行示例测试:

# C++
./red.e < red0.in
# Python
python3 red.py < red0.in

方式 2:标准输入输出交互

red2.cppred2.py 为基于标准输入输出的示例(错误)解决方案。C++ 使用 make 编译,生成 red2.e。运行使用 run.sh 脚本:

# C++
./run.sh "./red2.e" red0.in
# Python
./run.sh "python3 red2.py" red0.in

示例评测程序与正式评测使用的评测程序不同,可能不验证输入或函数参数的合法性。提交评测的代码将在样例上使用正式评测程序。

样例

假设 n=4,m=4n=4, m=4,道路连接城市对 (0,3),(0,2),(1,2),(2,3)(0, 3), (0, 2), (1, 2), (2, 3),维护成本分别为 3,1,2,43, 1, 2, 4。交互过程可能如下:

调用 结果 说明
DajN 44 获取城市数量 n=4n=4
DajDrogi {(0,3),(0,2),(1,2),(2,3)}\{(0,3), (0,2), (1,2), (2,3)\} 获取 m=4m=4 条道路列表。
Gwiazda([3, 1, 2]) 11 道路 11 在集合中成本最低。
Niezalezne(0, 2) 11 道路 00 成本高于道路 22
Gwiazda([3, 0]) 00 道路 00 成本低于道路 33
Niezalezne(2, 0) 1-1 道路 22 成本低于道路 00
Wynik([0, 2, 1]) - 正确提交保留道路集合。

附加样例

  1. n=200,m=199n=200, m=199,无法移除任何道路。
  2. n=1500,m=2998n=1500, m=2998,除一个城市外,其余城市形成环,剩余城市与环上每城相连。
  3. n=200000,m=300000n=200000, m=300000,道路 ii (0i<n)(0 \leq i < n) 连接城市 ii(i+1)modn(i+1) \bmod n,道路 n+in+i (0i<mn)(0 \leq i < m-n) 连接城市 ii(i+5)modn(i+5) \bmod n,成本为 i+1i+1

数据范围与提示

详细子任务附加限制及分值如下表所示。

子任务编号 附加限制 分值
11 n200,m300n \leq 200, m \leq 300 1818
22 n2000,m3000n \leq 2000, m \leq 3000 3333
33 m=nm = n 1212
44 mn+10m \leq n + 10 1616
55 无附加限制 2121

单次测试得分基于独立型询问次数 pp 和星型询问次数 qq,如下表所示:

p\qp \backslash q 0qn10 \leq q \leq n-1 n1<q2(n1)n-1 < q \leq 2 \cdot (n-1) 2(n1)<q2 \cdot (n-1) < q
0p15m0 \leq p \leq 15 \cdot m 100%100\% 75%75\% 40%40\%
15m<pmax(15,n)m15 \cdot m < p \leq \max(15, n) \cdot m 50%50\% 30%30\% 20%20\%
p>max(15,n)mp > \max(15, n) \cdot m 15%15\% 10%10\% 5%5\%

若答案错误或发生其他错误(运行错误、超时等),测试点得分为 00