CF938D Buy a Ticket
这个题都想不出来,感觉💊。
直接把所有的边权乘上两倍放到原来的图里去,每一个点$i$的初始$dis_i = a_i$,然后跑一遍最短路就没了。
时间复杂度$O(nlogn)$。
对于这些看上去很套路但是想不出来的题要联系学过的知识的本质多想想。
Code:
#include <cstdio> #include <cstring> #include <queue> #include <iostream> using namespace std; typedef long long ll; typedef pair <ll, int> pin; const int N = 2e5 + 5; int n, m, tot = 0, head[N]; ll dis[N]; bool vis[N]; struct Edge { int to, nxt; ll val; } e[N << 1]; inline void add(int from, int to, ll val) { e[++tot].to = to; e[tot].val = val; e[tot].nxt = head[from]; head[from] = tot; } template <typename T> inline void read(T &X) { X = 0; char ch = 0; T op = 1; for(; ch > '9'|| ch < '0'; ch = getchar()) if(ch == '-') op = -1; for(; ch >= '0' && ch <= '9'; ch = getchar()) X = (X << 3) + (X << 1) + ch - 48; X *= op; } priority_queue <pin> Q; void dij() { for(; !Q.empty(); ) { int x = Q.top().second; Q.pop(); if(vis[x]) continue; vis[x] = 1; for(int i = head[x]; i; i = e[i].nxt) { int y = e[i].to; if(dis[y] > dis[x] + e[i].val) { dis[y] = dis[x] + e[i].val; Q.push(pin(-dis[y], y)); } } } } int main() { read(n), read(m); for(int x, y, i = 1; i <= m; i++) { read(x), read(y); ll v; read(v); add(x, y, v * 2), add(y, x, v * 2); } for(int i = 1; i <= n; i++) { read(dis[i]); Q.push(pin(-dis[i], i)); } dij(); for(int i = 1; i <= n; i++) printf("%lld ", dis[i]); printf("\n"); return 0; }