1 条题解
-
0
最短路。
可以建立 个超级源点,红绿灯编号有什么数字就建立有向边指向对应源点边权如题,再建立有向边从源点指向该红绿灯边权为 。正常跑最短路,最后选出一家早餐店即可。
#include <bits/stdc++.h> using i64 = long long; using u32 = unsigned; using u64 = unsigned long long; void solve() { int n; std::cin >> n; std::vector<std::vector<std::pair<int, int>>> e(n + 12); for (int i = 0; i <= n; ++i) { int w; std::cin >> w; e[i].emplace_back(i + 1, w); e[i + 1].emplace_back(i, w); } for (int i = 0; i < n; ++i) { int u; std::cin >> u; while (u) { int t = u % 10; e[i + 1].emplace_back(n + 2 + t, t); e[n + 2 + t].emplace_back(i + 1, 0); u /= 10; } } std::vector<int> a(n + 1); for (int i = 1; i <= n; ++i) { std::cin >> a[i]; } auto dijkstra = [&](int s) -> std::vector<i64> { std::vector<i64> dis(n + 12, 1E18); std::vector<int> vis(n + 12); std::priority_queue<std::pair<i64, int>, std::vector<std::pair<i64, int>>, std::greater<>> pq; dis[s] = 0; pq.emplace(0, s); while (!pq.empty()) { auto [_, u] = pq.top(); pq.pop(); if (vis[u]) { continue; } vis[u] = 1; for (auto [v, w] : e[u]) { if (dis[v] > _ + w) { dis[v] = _ + w; pq.emplace(dis[v], v); } } } return dis; }; auto dis1 = dijkstra(0), dis2 = dijkstra(n + 1); i64 dis = 2E18, score = 0; for (int i = 1; i <= n; ++i) { i64 t = dis1[i] + dis2[i]; if (t < dis) { dis = t; score = a[i]; } else if (t == dis && a[i] > score) { score = a[i]; } } std::cout << dis << " " << score << "\n"; } int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int t; std::cin >> t; while (t--) { solve(); } return 0; }
- 1
信息
- ID
- 143
- 时间
- 3000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 4
- 已通过
- 3
- 上传者