Codeforces 938D Buy a Ticket (轉化建圖 + 最短路)
阿新 • • 發佈:2018-02-20
typedef ++ using fine return push 題意 aps stat
題目鏈接 Buy a Ticket
題意 給定一個無向圖。對於每個$i$ $\in$ $[1, n]$, 求$min\left\{2d(i,j) + a_{j}\right\}$
建立超級源點$n+1$, 對於每一條無向邊$(x, y, z)$,$x$向$y$連一條長度為$2z$的邊,反之亦然。
對於每個$a_{i}$, 從$i$到$n+1$連一條長度為$a_{i}$的邊,反之亦然。
然後跑一邊最短路即可。
#include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i, a, b) for (int i(a); i >= (b); --i) #define MP make_pair #define fi first #define se second typedef long long LL; const int N = 2e5 + 10; int n, m; LL dis[N]; struct node{ int u; LL w; friend bool operator < (const node &a, const node &b){ return a.w > b.w; } }; vector <node> v[N]; void dij(int s, LL dis[], vector <node> v[]){ priority_queue <node> q; static bool vis[N]; rep(i, 1, n) dis[i] = 1e18, vis[i] = false; q.push({s, 0}); dis[s] = 0; while (!q.empty()){ int u = q.top().u; q.pop(); if (vis[u]) continue; vis[u] = 1; for (auto edge : v[u]) if (dis[u] + edge.w < dis[edge.u]){ dis[edge.u] = dis[u] + edge.w; q.push({edge.u, dis[edge.u]}); } } } int main(){ scanf("%d%d", &n, &m); rep(i, 1, m){ int x, y; LL z; scanf("%d%d%lld", &x, &y, &z); v[x].push_back({y, z * 2}); v[y].push_back({x, z * 2}); } rep(i, 1, n){ LL x; scanf("%lld", &x); v[n + 1].push_back({i, x}); v[i].push_back({n + 1, x}); } dij(n + 1, dis, v); rep(i, 1, n) printf("%lld ", dis[i]); return 0; }
Codeforces 938D Buy a Ticket (轉化建圖 + 最短路)