传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1003
【题解】
瞎预处理瞎[i,j]天的最短路
dp处理即可。f[i]=min(f[j]+dis[i,j,n]*(i-j))+K
# include <queue> # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2e3 + 10, N = 30; const int mod = 1e9+7; # define RG register # define ST static int n, day, K, m; int head[N], nxt[M], to[M], w[M], tot=0; inline void add(int u, int v, int _w) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; w[tot] = _w; } inline void adde(int u, int v, int _w) { add(u, v, _w); add(v, u, _w); } int pn; struct pa { int p, a, b; pa() {} pa(int p, int a, int b) : p(p), a(a), b(b) {} }p[M]; bool cannot[N]; ll dis[110][110][N]; bool vis[N]; ll f[110]; queue<int> q; inline void spfa(int si, int sj) { ll *d = dis[si][sj]; memset(vis, 0, sizeof vis); while(!q.empty()) q.pop(); for (int i=1; i<=n; ++i) d[i] = 1e9; q.push(1); d[1] = 0; while(!q.empty()) { int top = q.front(); q.pop(); vis[top] = 0; for (int i=head[top]; i; i=nxt[i]) { if(d[to[i]] > d[top] + w[i] && !cannot[to[i]]) { d[to[i]] = d[top] + w[i]; if(!vis[to[i]]) { q.push(to[i]); vis[to[i]] = 1; } } } } } int main() { cin >> day >> n >> K >> m; for (int i=1, u, v, l; i<=m; ++i) { scanf("%d%d%d", &u, &v, &l); adde(u, v, l); } cin >> pn; for (int i=1; i<=pn; ++i) scanf("%d%d%d", &p[i].p, &p[i].a, &p[i].b); for (int i=1; i<=day; ++i) for (int j=i; j<=day; ++j) { for (int k=1; k<=n; ++k) cannot[k] = 0; for (int k=1; k<=pn; ++k) { if(p[k].a > j || p[k].b < i) continue; cannot[p[k].p] = 1; } spfa(i, j); } f[0] = 0; for (int i=1; i<=day; ++i) f[i] = 1e9; for (int i=1; i<=day; ++i) for (int j=0; j<=i-1; ++j) f[i] = min(f[i], f[j] + dis[j+1][i][n]*(i-j) + K); printf("%lld\n", f[day] - K); return 0; }