[USACO] Piggy Back
题目大概意思是一个无向图,Bessie 从 1 号仓库走到 n 号(每次花费 x), Elsie 从 2 号仓库走到 n 号(每次花费 y),如果两个人走同一条路花费 z,求总花费最小。
跑三遍最短路,别得到 Bessie 从 1 号仓库出发的最短路,Elsie 从 2 号仓库出发的最短路,和从 n 出发到其他每个点的最短路。
在走到相遇点之前,两人一定走的是对应最短路才能减小花费
不难得出 \(ans = min(ans, x * d1[i] + y * d2[i] + z * d3[i])\)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cstring>
#define rint register int
#define endl '\n'
using std::cin;
using std::cout;
const int inf = 0x3f3f3f3f;
const int N = 1e6 + 5;
const int M = 4e6 + 5;
int n, m, s;
int idx, h[N], e[M], ne[M], d1[N], d2[N], d3[N];
bool v[N];
std::priority_queue<std::pair<int, int>> q;
void add(int a, int b)
{
e[++idx] = b, ne[idx] = h[a], h[a] = idx;
}
void dijkstra(int s, int *dist)
{
for (rint i = 1; i <= n; i++)
{
dist[i] = inf;
}
memset(v, 0, sizeof v);
dist[s] = 0;
q.push(std::make_pair(0, s));
while (!q.empty())
{
int x = q.top().second;
q.pop();
if (v[x])
{
continue;
}
v[x] = 1;
for (rint i = h[x]; i; i = ne[i])
{
int y = e[i];
int z = 1;
if (dist[y] > dist[x] + z)
{
dist[y] = dist[x] + z;
q.push(std::make_pair(-dist[y], y));
}
}
}
}
int x, y, z;
int main()
{
cin >> x >> y >> z >> n >> m;
for (rint i = 1; i <= m; i++)
{
int a, b;
cin >> a >> b;
add(a, b);
add(b, a);
}
dijkstra(1, d1);
dijkstra(2, d2);
dijkstra(n, d3);
int ans = inf;
for (rint i = 1; i <= n; i++)
{
ans = std::min(ans, x * d1[i] + y * d2[i] + z * d3[i]);
}
cout << ans << endl;
return 0;
}