NC14700 追债之旅
追债之旅
https://ac.nowcoder.com/acm/problem/14700
题目大意
给定一张无向图,每条边有费用,每走 条边会有额外费用
,至多走
条边。问从点
到点
的最小费用路。
题解
把每一个点拆成 个点,相当于对点记录一下时间即可直接套用 Dijkstra 算法。
#include <bits/stdc++.h> #define REP(temp, init_val, end_val) for (int temp = init_val; temp <= end_val; ++temp) #define REPR(temp, init_val, end_val) for (int temp = init_val; temp >= end_val; --temp) #define fst first #define snd second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> intpair; int read(){ int f = 1, x = 0; char c = getchar(); while (c < '0' || c > '9'){if(c == '-') f = -f; c = getchar();} while (c >= '0' && c <= '9')x = x * 10 + c - '0', c = getchar(); return f * x; } int n, m, k; priority_queue<pair<int, intpair > > pq; int dis[1005][12]; int to[20005], nxt[20005], w[20005], at[1005] = {0}, cnt = 0; int c[12]; void init(){ n = read(), m = read(), k = read(); REP(i, 1, m){ int u = read(), v = read(), ww = read(); to[++cnt] = v, nxt[cnt] = at[u], w[cnt] = ww, at[u] = cnt; to[++cnt] = u, nxt[cnt] = at[v], w[cnt] = ww, at[v] = cnt; } REP(i, 1, k){ c[i] = read(); } } void solve(){ memset(dis, 0x3f, sizeof(dis)); dis[1][0] = 0; pq.push(make_pair(0, make_pair(1, 0))); for (; ; ){ while (!pq.empty()){ if (-pq.top().fst > dis[pq.top().snd.fst][pq.top().snd.snd]) pq.pop(); else break; } if (pq.empty()) break; int d = -pq.top().fst; int p = pq.top().snd.fst; int tm = pq.top().snd.snd; pq.pop(); if (tm == k) continue; for (int i = at[p]; i; i = nxt[i]){ if (d + w[i] + c[tm + 1] < dis[to[i]][tm + 1]) dis[to[i]][tm + 1] = d + w[i] + c[tm + 1], pq.push(make_pair(-dis[to[i]][tm + 1], make_pair(to[i], tm + 1))); } } int ans = 0x3f3f3f3f; REP(i, 0, k) ans = min(ans, dis[n][i]); printf("%d\n", ans == 0x3f3f3f3f ? -1: ans); } int main(){ init(); solve(); return 0; }