CF95C
跑两遍最短路。
设 $dis_{i,j}$ 表示从 $i$ 走到 $j$ 的最短路径,注意这里不是乘车。
对于每一个在 $i$ 位置的司机,
如果 $dis_{i,j} \leq t_i$,则 $i$ 司机就可以从 $i$ 开到 $j$,花费为 $c_i$,
我们就再建一个图,若能乘车从 $i$ 到 $j$ 并要花费 $c$,那么我们就连一条从 $i$ 到 $j$,长度为 $c$ 的边。
最后我们在上图的基础上,求一遍最短路,求出 $x$ 到 $y$ 的最小花费。
备注:发现 $n, m \leq 1000$,$dis_{i, j}$ 就 $n$ 遍 Dijskra 算出即可。
#include <queue>
#include <vector>
#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = 1010;
const ll inf = (1ll << 60);
int n, m;
int vis[N];
ll dis[N][N];
int t[N], c[N];
vector <pair <int, ll> > e[N]; // 用 vector 存图
int read() {
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
if (f == 1) return x;
else if (f == -1) return -x;
}
void dij (int s) { // 以 s 为起点求到其他点的最短路
priority_queue <pair<ll, int> > pq;
for (int i = 1; i <= n; ++i) {
dis[s][i] = inf; vis[i] = false; // 每次都要把 vis[i] 清空
}
pq.push (make_pair (0, s)); dis[s][s] = 0;
while (!pq.empty()) {
int u = pq.top().second; ll d = -pq.top().first; pq.pop();
if (vis[u]) continue;
vis[u] = true;
for (int i = 0; i < e[u].size(); ++i) {
pair <int, ll> v = e[u][i];
if (dis[s][v.first] > d + v.second) {
dis[s][v.first] = d + v.second; pq.push (make_pair (-dis[s][v.first], v.first)); // 由于是大根堆,所以进入 pq 的权值变号,保证是小的先。
}
}
}
}
int main() {
int x, y;
n = read(); m = read(); x = read(); y = read();
for (int i = 1; i <= m; ++i) {
int u, v, w; u = read(); v = read(); w = read();
e[u].push_back (make_pair (v, w)); e[v].push_back (make_pair (u, w));
}
for (int i = 1; i <= n; ++i) {
t[i] = read(); c[i] = read();
}
for (int i = 1; i <= n; ++i) {
dij (i); // 对于每个 i 都求一次最短路
}
for (int i = 1; i <= n; ++i) {
e[i].clear(); // 要新建图,别忘清空!!!
}
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (dis[i][j] <= t[i] && i != j) { // 注意:i != j
e[i].push_back (make_pair (j, c[i]));
}
}
}
dij (x); // 起点是 x,不是 1。
if (dis[x][y] == inf) printf ("-1\n");
else printf ("%lld\n", dis[x][y]);
return 0;
}
浙公网安备 33010602011771号