Description
小明现在要追讨一笔债务,已知有n座城市,每个城市都有编号,城市与城市之间存在道路相连(每条道路都是双向的),经过任意一条道路需要支付费用。小明一开始位于编号为1的城市,欠债人位于编号为n的城市。小明每次从一个城市到达另一个城市需要耗时1天,而欠债人每天都会挥霍一定的钱,等到第k天后(即第k+1天)他就会离开城n并再也找不到了。小明必须要在他离开前抓到他(最开始为第0天),同时希望自己的行程花费和欠债人挥霍的钱的总和最小,你能帮他计算一下最小总和吗?
Solution
显然是最短路问题,求1到n的最短路,由于多出了个欠债人的影响,考虑分层图最短路,用 代表第
天到达
城市的最短路径,那么剩下的问题就可以用
去解决了,后一天的状态能从当前天转移过来。
WA了很多次,没想到当成n条边输入了0.0
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
const int mod = 1e9 + 7;
int a[N], dist[N][11], n, m, k;
bool vis[N][11];
struct qnode {
int v, cost, day;
bool operator < (const qnode &r)const{
return cost > r.cost;
}
qnode(int _v = 0, int _cost = 0, int _day = 0): v(_v), cost(_cost), day(_day){}
};
struct Edge {
int v, cost;
Edge(int _v = 0, int _cost = 0): v(_v), cost(_cost){}
};
vector<Edge> G[N];
void Dijkstra(int n, int start) {
for(int i = 1; i <= n; i++) {
for(int j = 0; j <= 10; j++) {
dist[i][j] = 1e9;
vis[i][j] = false;
}
}
priority_queue<qnode> q;
dist[start][0] = 0;
q.push(qnode(start, 0, 0));
while(!q.empty()) {
qnode tmp = q.top(); q.pop();
int u = tmp.v;
int day = tmp.day;
if(vis[u][day]) continue;
vis[u][day] = true;
for(int i = 0; i < G[u].size(); i++) {
int v = G[u][i].v;
int cost = G[u][i].cost;
int j = day + 1;
if(j > k) continue;
if(!vis[v][j] && dist[v][j] > dist[u][j - 1] + cost + a[j]) {
dist[v][j] = dist[u][j - 1] + cost + a[j];
q.push(qnode(v, dist[v][j], j));
}
}
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> n >> m >> k;
for(int i = 1; i <= m; i++) {
int x, y, z; cin >> x >> y >> z;
G[x].push_back({y, z}), G[y].push_back({x, z});
}
for(int i = 1; i <= k; i++) cin >> a[i];
Dijkstra(n, 1);
int ans = 1e9;
for(int i = 0; i <= k; i++) {
ans = min(ans, dist[n][i]);
}
if(ans != 1e9)
cout << ans << "\n";
else cout << -1 << "\n";
return 0;
} 
京公网安备 11010502036488号