DP
直接考虑 d p dp dp 。定义 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示到 i i i 这个点用 j j j 次优惠的最短路径。
对于 i i i 这个点,只有用与不用优惠两种情况,由此可得状态转移方程:
(其中 u u u 表示上一个点。
int val = min(dp[u][j] + w, dp[u][j + 1]);
dp[u][j] = min(dp[u][j], val);
然后SPFA边跑边进行更新。
但这样会超时,只有 90 90 90 分(有人玄学Dijk在 p o t a t o potato potato o n l i n e online online j u d g e judge judge 上卡过了,但在某谷被 h a c k hack hack 了。
代码1
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 10005;
const int INF = 0x3f3f3f3f;
int Min(int x, int y) {
return x < y ? x : y; }
struct edge {
int v, c;
edge() {
}
edge(int V, int C) {
v = V;
c = C;
}
};
vector<edge> mp[MAXN];
void Add_Edge(int x, int y, int w) {
mp[x].push_back(edge(y, w));
mp[y].push_back(edge(x, w));
return;
}
int dp[MAXN][15];
int n, m, k, s, t;
void read(int &a) {
a = 0;
int k = 1;
char s = getchar();
while (s < '0' || s > '9') {
if (s == '-')
k = -1;
s = getchar();
}
while (s >= '0' && s <= '9') {
a =