题解:CF1915G Bicycles
a_small_penguin · · 题解
思路:分层图最短路
明显,在有多辆车的情况下,使用速度系数最小的车最优。
但是,如果直接跑普通的最短路,样例会过不了。
为什么?
首先观察样例所建的图:
当从
但是,实际上路径为
所以我们对于每一个速度系数建一个层,跑一遍分层图最短路即可。注意能往下一层转移的,就不必再在同层转移了。
对比:
对于答案,即为
code:
#include <bits/stdc++.h>
using namespace std;
#define inf 0x7fffffffffffffff
int n, m;
struct V{
int s;
vector<array<int, 2> > e;
long long d[1009];
bitset<1009> c;
}v[1009];
priority_queue<array<long long, 3>, vector<array<long long, 3> >, greater<array<long long, 3> > > p;
inline void dij() {
p.push({0, 1, v[1].s});
v[1].d[v[1].s] = 0;
while(p.size()) {
int u = p.top()[1];
int k = p.top()[2];
p.pop();
if(v[u].c[k]) continue;
v[u].c = 1;
for(auto to: v[u].e) {
if(v[to[0]].d[min(k, v[to[0]].s)] > v[u].d[k] + to[1] * k) {
v[to[0]].d[min(k, v[to[0]].s)] = v[u].d[k] + to[1] * k;
p.push({v[to[0]].d[min(k, v[to[0]].s)], to[0], min(k, v[to[0]].s)});
}
}
}
}
inline void sovel() {
cin >> n >> m;
fill(v + 1, v + n + 1, v[0]);
for(int i = 1, _u, _v, _w; i <= m; i++) {
cin >> _u >> _v >> _w;
v[_u].e.push_back({_v, _w});
v[_v].e.push_back({_u, _w});
}
for(int i = 1; i <= n; i++) {
fill(v[i].d + 1, v[i].d + 1001, inf);
cin >> v[i].s;
}
dij();
long long ans = inf;
for(int i = 1; i <= 1000; i++) {
ans = min(ans, v[n].d[i]);
}
cout << ans << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int _T = 1;
cin >> _T;
while(_T--) {
sovel();
}
return 0;
}