题面:有n座城市,从城市i到城市j可以坐班车,需要A*D[i][j]时间,也可以坐火车,需要B*D[i][j]+C时间。可以从班车换到火车,但反过来不行。换乘时间不计,求从城市1到城市n的最短时间。
范围:n<1000; A,B,C<1E6; D[i]][j]<1E6并且D[i][i]=0。
思路:先预处理出任意两城市之间的耗时,包括班车D[i][j]和火车d[i][j],然后边跑dijkstra边dp,即班车后续可以是班车或火车,而火车后续只能是火车。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a; i<=b; i++)
#define per(i,a,b) for(int i=b; i>=a; i--)
const int N = 1005;
const int inf = 1E18;
int n, A, B, C, D[N][N], d[N][N], ans[N][2];
void dijkstra(int s) {
rep(i,1,n) ans[i][0] = ans[i][1] = inf;
priority_queue<tuple<int,int,int>> q;
q.push({0,s,0});
q.push({0,s,1});
while (!q.empty()) {
auto [c,x,f] = q.top(); q.pop();
if (ans[x][0] == inf && f == 0) {
ans[x][0] = -c;
rep(i,1,n) {
if (ans[i][0]==inf) {
q.push({c-D[x][i],i,0});
}
if (ans[i][1]==inf) {
q.push({c-d[x][i],i,1});
}
}
}
if (ans[x][1] == inf) {
ans[x][1] = -c;
rep(i,1,n) {
if (ans[i][1]==inf) {
q.push({c-d[x][i],i,1});
}
}
}
}
}
void solve() {
cin >> n >> A >> B >> C;
rep(i,1,n) rep(j,1,n) {
cin >> D[i][j];
if (i != j) {
d[i][j] = D[i][j] * B + C;
D[i][j] = D[i][j] * A;
}
}
dijkstra(1);
cout << min(ans[n][0],ans[n][1]) << "\n";
}
signed main() {
cin.tie(0)->sync_with_stdio(0);
int t = 1;
while (t--) solve();
return 0;
}
标签:班车,int,短路,ans,push,inf,rep,abc325E
From: https://www.cnblogs.com/chenfy27/p/18062276