专栏文章

题解:CF1915G Bicycles

CF1915G题解参与者 2已保存评论 1

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
1 条
当前快照
1 份
快照标识符
@miphd1z6
此快照首次捕获于
2025/12/03 12:01
3 个月前
此快照最后确认于
2025/12/03 12:01
3 个月前
查看原文

思路:分层图最短路

明显,在有多辆车的情况下,使用速度系数最小的车最优。
但是,如果直接跑普通的最短路,样例会过不了。
为什么?
首先观察样例所建的图:
当从 1122 时所花的时间是 1010。如果直接跑最短路的话,路径是 12451 \to 2 \to 4 \to 5。总时间是 2×5+2×5+2×1=222 \times 5 + 2 \times 5 + 2\times 1 = 22
但是,实际上路径为 1232451 \to 2 \to 3 \to 2 \to 4 \to 5 是会更优的,总时间是 2×5+1×2+1×1+5×1+1×1=192 \times 5 + 1 \times 2 + 1 \times 1 + 5 \times 1 + 1\times 1 = 19。观察两个路径的区别,不难发现,在第二种中虽然重复走了两遍 232 \to 3 这换取了速度系数更小,使得总时间更少
所以我们对于每一个速度系数建一个层,跑一遍分层图最短路即可。注意能往下一层转移的,就不必再在同层转移了。
对比:
对于答案,即为 mini=11000dn,i\min^{1000}_{i = 1} d_{n,i}。其中 di,jd_{i,j} 表示从 11ii,且最小速度系数最小值为 jj 时的最短时间。
code:
CPP
#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;

}

评论

1 条评论,欢迎与作者交流。

正在加载评论...