P3110 [USACO14DEC]Piggy Back S 題解
阿新 • • 發佈:2020-09-18
Link
P3110 [USACO14DEC]Piggy Back S
solve
這道題很早以前做過,所以想清楚也就好了。
對於Bessie和Elsie來說,只能背一次,背上了就不能下來了,所以我們可以列舉背的點,我們可以算出Bessie到背的點的最短路和Elsie到背的點最短路,加上背的點到終點的最短路,都是可以提前預處理出來的,最後取一個min就好了。
code
#include <bits/stdc++.h>//萬能頭大法好 using namespace std; const int N = 1e7; const int maxn = 200005; const int maxm = 500005; typedef long long ll; //做題的好習慣 typedef long double ld; #define ms(a) memset(a, 0, sizeof(a)) int n, m, a, b, c;//a,b,c分別是題目中的B、E、P struct Edge{ int nxt, to, w; }e[maxm]; int head[maxn], cnt; void addEdge(int u, int v, int w) { e[++cnt] = (Edge){head[u], v, w}, head[u] = cnt; } int vis[maxn], dis[maxn]; //d1、d2、dn分別為從1、2、n出發的最短路 ll d1[maxn], d2[maxn], dn[maxn], minn = 1e12;//不清楚?最好用long long吧…… void dijkstra(int s) { for (int i = 1; i <= n; i++) dis[i] = 0x3f3f3f3f; priority_queue< pair<int, int> > q; q.push(make_pair(0, s)); dis[s] = 0; while (q.size()) { int u = q.top().second; q.pop(); if (vis[u]) continue; vis[u] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].to; if (dis[v] > dis[u] + e[i].w) { dis[v] = dis[u] + e[i].w; q.push(make_pair(-dis[v], v)); } } } } int main() { cin >> a >> b >> c >> n >> m; if (c > a + b) c = a + b; for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; addEdge(u, v, 1); addEdge(v, u, 1); } //剩下的不想註釋了,大家看看解題技巧就明白了 dijkstra(1); for (int i = 1; i <= n; i++) d1[i] = (ll)dis[i] * a; ms(vis); dijkstra(2); for (int i = 1; i <= n; i++) d2[i] = (ll)dis[i] * b; ms(vis); dijkstra(n); for (int i = 1; i <= n; i++) dn[i] = (ll)dis[i] * c; for (int i = 1; i <= n; i++) if (d1[i] + d2[i] + dn[i] < minn) minn = d1[i] + d2[i] + dn[i]; cout << minn; return 0; }