题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=2763
题解:
d[x][kk]表示从s到x用了kk次免费机会的最少花费。
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #include<vector> #include<cstring> #define mp make_pair #define X first #define Y second using namespace std; const int maxn = 10000; int n, m, k; vector<pair<int, int> > G[maxn]; int d[maxn][22]; bool inq[maxn][22]; void spfa(int s) { memset(d, 0x7f, sizeof(d)); memset(inq, 0, sizeof(inq)); queue<pair<int,int> > Q; d[s][0] = 0, inq[s][0] = 1, Q.push(mp(s,0)); while (!Q.empty()) { int u = Q.front().X,kk=Q.front().Y; Q.pop(); inq[u][kk] = 0; for (int i = 0; i < G[u].size(); i++) { int v = G[u][i].X, w = G[u][i].Y; if (d[v][kk]>d[u][kk] + w) { d[v][kk] = d[u][kk] + w; if (!inq[v][kk]) { inq[v][kk] = 1, Q.push(mp(v, kk)); } } if (kk + 1 <= k&&d[v][kk + 1] > d[u][kk]) { d[v][kk + 1] = d[u][kk]; if (!inq[v][kk + 1]) { inq[v][kk + 1] = 1, Q.push(mp(v, kk + 1)); } } } } } void init() { for (int i = 0; i < n; i++) G[i].clear(); } int main() { while (scanf("%d%d%d", &n, &m, &k) == 3) { init(); int s, t; scanf("%d%d", &s, &t); for (int i = 0; i < m; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); G[u].push_back(mp(v, w)); G[v].push_back(mp(u, w)); } spfa(s); printf("%d ", d[t][k]); } return 0; }