Official
H - Roads and Gates Editorial by en_translator
By creating sur-vertices \(W _ S\) and \(W _ T\) and allowing travel from vertex \(i\) to \(W _ S\) in \(X _ i\) minutes, from \(W _ S\) to \(W _ T\) in \(Y\) minutes, and from \(W _ T\) to \(j\) in \(X _ j\) minutes, the problem is reduced to a single-source shortest path problem on a graph with \((N+2)\) vertices and \((2N+M+1)\) edges.
This can be solved with an algorithm like Dijkstra’s algorithm.
The following is sample code.
#include <iostream>
#include <vector>
#include <queue>
#include <ranges>
int main() {
using namespace std;
unsigned N, M, Y;
cin >> N >> M >> Y;
vector<vector<pair<unsigned, unsigned>>> edges(N + 2);
for (unsigned i{}; i < M; ++i) {
unsigned u, v, T;
cin >> u >> v >> T;
edges[--u].emplace_back(--v, T);
edges[v].emplace_back(u, T);
}
for (unsigned i{}; i < N; ++i) {
unsigned X;
cin >> X;
edges[i].emplace_back(N, X); // From each vertex to W_S
edges[N + 1].emplace_back(i, X); // From W_T to each vertex
}
edges[N].emplace_back(N + 1, Y); // from W_S to W_T
// Use Dijkstra's algorithm to find a shortest path
vector<unsigned> distance(N + 2, 3000000000);
priority_queue<pair<unsigned, unsigned>, vector<pair<unsigned, unsigned>>, greater<>> pq;
pq.emplace(distance[0] = 0, 0);
while (!empty(pq)) {
const auto [dist, now]{pq.top()};
pq.pop();
if (distance[now] < dist) continue;
for (const auto& [next, cost] : edges[now])
if (distance[next] > dist + cost)
pq.emplace(distance[next] = dist + cost, next);
}
for (const auto d : distance | views::take(N) | views::drop(1))
cout << d << " ";
cout << endl;
return 0;
}