当前位置: 首页 > news >正文

【ICPC】The 2024 ICPC Kunming Invitational Contest J

The Quest for El Dorad

#最短路 #图论 #数据结构 #二分

题目描述

There is a kingdom with n n n cities and m m m bi-directional railways connecting the cities. The i i i-th railway is operated by the c i c_i ci-th railway company, and the length of the railway is l i l_i li.

You’d like to travel around the country starting from city 1 1 1. For your travel, you have bought k k k railway tickets. The i i i-th ticket can be represented by two integers a i a_i ai and b i b_i bi, meaning that if you use this ticket, you can travel through some railways in one go, as long as they’re all operated by company a i a_i ai and their total length does not exceed b i b_i bi. It is also allowed to just stay in the current city when using a ticket. You can only use the tickets one at a time, and you can only use each ticket once.

As you find it a burden to determine the order to use the tickets, you decided to use the tickets just in their current order. More formally, you’re going to perform k k k operations. In the i i i-th operation, you can either choose to stay in the current city u u u; Or choose a different city v v v, such that there exists a path from city u u u to city v v v where all railways in the path are operated by company a i a_i ai and the total length of railways does not exceed b i b_i bi, and finally move to city v v v.

For each city, determine if it is possible to arrive in that city after using all k k k tickets.

输入格式

There are multiple test cases. The first line of the input contains an integer T T T indicating the number of test cases. For each test case:

The first line contains three integers n n n, m m m, and k k k ( 2 ≤ n ≤ 5 × 1 0 5 2 \le n \le 5 \times 10^5 2n5×105, 1 ≤ m ≤ 5 × 1 0 5 1 \le m \le 5 \times 10^5 1m5×105, 1 ≤ k ≤ 5 × 1 0 5 1 \le k \le 5 \times 10^5 1k5×105) indicating the number of cities, the number of railways and the number of tickets.

For the following m m m lines, the i i i-th line contains four integers u i u_i ui, v i v_i vi, c i c_i ci, and l i l_i li ( 1 ≤ u i , v i ≤ n 1 \le u_i, v_i \le n 1ui,vin, u i ≠ v i u_i \ne v_i ui=vi, 1 ≤ c i ≤ m 1 \le c_i \le m 1cim, 1 ≤ l i ≤ 1 0 9 1 \le l_i \le 10^9 1li109) indicating that the i i i-th railway connects city u i u_i ui and v i v_i vi. It is operated by company c i c_i ci and its length is l i l_i li. Note that there might be multiple railways connecting the same pair of cities.

For the following k k k lines, the i i i-th line contains two integers a i a_i ai and b i b_i bi ( 1 ≤ a i ≤ m 1 \le a_i \le m 1aim, 1 ≤ b i ≤ 1 0 9 1 \le b_i \le 10^9 1bi109) indicating that if you use the i i i-th ticket, you can travel through some railways in one go, if they’re all operated by company a i a_i ai and their total length does not exceed b i b_i bi.

It’s guaranteed that the sum of n n n, the sum of m m m, and the sum of k k k of all test cases will not exceed 5 × 1 0 5 5 \times 10^5 5×105.

输出格式

For each test case, output one line containing one string s 1 s 2 ⋯ s n s_1s_2\cdots s_n s1s2sn of length n n n where each character is either 0 0 0 or 1 1 1. If you can travel from city 1 1 1 to city i i i with these k k k tickets, then s i = 1 s_i = 1 si=1; Otherwise s i = 0 s_i = 0 si=0.

样例 #1

样例输入 #1

2
5 6 4
1 2 1 30
2 3 1 50
2 5 5 50
3 4 6 10
2 4 5 30
2 5 1 40
1 70
6 100
5 40
1 30
3 1 1
2 3 1 10
1 100

样例输出 #1

11011
100

解题思路

首先,操作顺序是固定的,对于一条线路(边),我们能做的只有选择这张车票坐下去(如果可以),或者等待到下一张可行的票。

因此,这可以看做是一个 d i j k s t r a dijkstra dijkstra的最短路,我们以操作次数作为第一关键字,以已经乘坐了的线路长度作为第二关键字,从小到大的取出来转移:

1. 1. 1. 如果当前路径是同一个公司,并且加上这条边的权重不会超过这张票的最大权重,那么我们直接转移

2. 2. 2. 反之,我们就可以找到第一个为这个公司,并且票的权重大于这条边的票作为转移。

那么,对于一个无序的序列,找到 [ l , r ] [l,r] [l,r]第一个大于等于 x x x的数,可以使用二分+ R M Q RMQ RMQ算法来实现,这里使用 S T ST ST表,预处理后可以配合二分实现 l o g n log_n logn查询。

总体时间复杂度在 O ( k l o g 2 k + n l o g 2 ( n + m ) l o g 2 k ) O(klog_2k+ nlog_2(n+m)log_2k) O(klog2k+nlog2(n+m)log2k)

代码


using pii = std::pair<int, int>;const int N = 5e5 + 10;int LOG[N];
struct STList {int n, k;std::vector<std::vector<int>> Max;STList() {}STList(const std::vector<int>& a) {init(a);}void init(const std::vector<int>& a) {n = a.size();k = LOG[n] + 1;Max.assign(n, std::vector<int>(k));for (int i = 0; i < n; ++i) {Max[i][0] = a[i];}for (int j = 1; j < k; ++j) {for (int i = 0; i + (1LL << j) <= n; ++i)Max[i][j] = std::max(Max[i][j - 1], Max[i + (1LL << (j - 1))][j - 1]);}}int query(int l, int r) {int j = LOG[r - l + 1];return std::max(Max[l][j], Max[r - (1LL << j) + 1][j]);}
};struct node {int v, c, dis;
};void solve() {int n, m, k;std::cin >> n >> m >> k;std::vector<std::vector<node>>e(n + 1);for (int i = 1; i <= m; ++i) {int u, v, c, dis;std::cin >> u >> v >> c>> dis;e[u].push_back({ v,c,dis });e[v].push_back({ u,c,dis });}std::vector<std::vector<int>>mx(m + 1);std::vector<pii>a(k + 1); //c - lenstd::vector<std::vector<int>>idx(m + 1);for (int i = 1; i <= k; ++i) {int c, l;std::cin >> c >> l;a[i] = { c,l };mx[c].push_back(l);idx[c].push_back(i);}std::vector<STList>ST(m + 1);for (int i = 1; i <= m; ++i) {if (mx[i].empty()) continue;ST[i].init(mx[i]);}std::vector<int> ok(n + 1), vis(n + 1);auto dijkstra = [&]() {//turn - dis - v std::priority_queue<std::array<int,3>, std::vector<std::array<int, 3>>,greater<>>pq; pq.push({ 1,0,1 });while (pq.size()) {auto [turn, dis, u] = pq.top(); pq.pop();if (vis[u]) continue;vis[u] = 1; ok[u] = 1;for (auto& [v, C, Dis] : e[u]) {if (mx[C].empty()) continue;auto& [c, D] = a[turn];if (C == c && Dis + dis <= D) {if (vis[v] == 0) {pq.push({ turn, Dis + dis, v });}continue;}auto pos = lower_bound(idx[C].begin(), idx[C].end(), turn + 1) ;if (pos == idx[C].end()) continue;int L = std::distance(idx[C].begin(), pos), R = idx[C].size() - 1;if (ST[C].query(L, R) < Dis) continue;int l = L, r = R, ans = -1;while (l <= r) {int mid = l + r >> 1;if (ST[C].query(l, mid) >= Dis) {r = mid - 1;ans = idx[C][mid];}else {l = mid + 1;}}pq.push({ ans,Dis,v });}}};dijkstra();for (int i = 1; i <= n; ++i) {std::cout << ok[i];}std::cout << "\n";}void init() {LOG[0] = -1;for (int i = 1; i < N; ++i) {LOG[i] = LOG[i >> 1] + 1;}}
signed main() {std::ios::sync_with_stdio(0);std::cin.tie(0);std::cout.tie(0);int t = 1;std::cin >> t;init();while (t--) {solve();}
}

http://www.mrgr.cn/news/49014.html

相关文章:

  • Kubernetes 实战之旅:从 0 到 1 搭建完整集群的奇妙征程
  • 计算机毕设选题推荐【人工智能专业】
  • [论文精读]Active and Semi-Supervised Graph Neural Networks for Graph Classification
  • 交叉编译--目标平台aarch64 ubuntu 22.04
  • 【AI绘画】Midjourney进阶:三分线构图详解
  • (全网独家)面试要懂运维真实案例:HDFS重新平衡(HDFS Balancer)没触发问题排查
  • 【C++】map和set的介绍以及用法
  • 记录使用appium+夜神模拟器测试多设备时selenium和appium版本不兼容带来的问题
  • 限界上下文(Bounded Context)
  • 开发指南072-模型定义
  • 【Power Query】List.Max List.Min
  • unpacking
  • 软考高级软件架构师论文——论Web系统的测试技术及其应用
  • 力扣刷题之3158.求出出现两次数字的XOR值
  • javaScripts 知识点一 (面试题)
  • InfluxDB持久层封装
  • 全能PDF工具集 | PDF Shaper Ultimate v14.6 便携版
  • 【藏于山中的妖怪,隐入尘烟山海】
  • 【ICESat-2(Ice, Cloud and land Elevation Satellite-2)简介】
  • 计算机毕设选题推荐【软件工程专业】