上古省选
最短路+$dp$
先预处理出第$i$天到第$j$天的最短路长度(在限制条件下的),然后就是一个标准的一维多段$dp$
令$f[i]$表示前$i$天的最小花费,只需枚举前一段的结尾$j$(即$j+1$到$i$的最短路是一样的)
有$$f[i] = min\left \{ f[j]+(i-j)*low[j+1][i]+k \right \}$$
$low[j+1][i]$表示第$i$天到第$j$天的最短路长度
上代码
1 #include <iostream>
2 #include <algorithm>
3 #include <cstdio>
4 #include <cstring>
5 #include <queue>
6 #define ll long long
7 using namespace std;
8
9 template <typename T> void in(T &x) {
10 x = 0; T f = 1; char ch = getchar();
11 while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
12 while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
13 x *= f;
14 }
15
16 template <typename T> void out(T x) {
17 if(x < 0) x = -x , putchar('-');
18 if(x > 9) out(x/10);
19 putchar(x%10 + 48);
20 }
21 //-------------------------------------------------------
22
23 int n,m,k,_e,d;
24 int vis[21],del[21],cls[21][101];
25 ll dis[21],low[101][101],f[101];
26
27 struct edge {
28 int v,w,nxt;
29 edge(int v = 0,int w = 0,int nxt = 0):v(v),w(w),nxt(nxt){};
30 }e[20002];int head[21],e_cnt;
31
32 void add(int u,int v,int w) {
33 e[++e_cnt] = edge(v,w,head[u]); head[u] = e_cnt;
34 }
35
36 struct node {
37 int id; ll dis;
38 node(int id = 0,ll dis = 0):id(id),dis(dis){};
39 bool operator < (const node &x) const {
40 return dis > x.dis;
41 }
42 };
43
44 ll dijkstra(int a,int b) {
45 memset(dis,0x3f,sizeof(dis)); dis[1] = 0;
46 memset(vis,0,sizeof(vis));
47 memset(del,0,sizeof(del));
48 for(int i = 1;i <= m; ++i) {
49 for(int j = a;j <= b; ++j) {
50 if(cls[i][j]) {
51 del[i] = 1; break;
52 }
53 }
54 }
55 priority_queue <node> q;
56 q.push(node(1,0));
57 while(!q.empty()) {
58 node _u = q.top(); q.pop();
59 int u = _u.id;
60 if(vis[u]) continue;
61 vis[u] = 1;
62 for(int i = head[u]; i;i = e[i].nxt) {
63 int v = e[i].v;
64 if(del[v]) continue;
65 if(dis[v] > dis[u] + e[i].w) {
66 dis[v] = dis[u] + e[i].w;
67 q.push(node(v,dis[v]));
68 }
69 }
70 }
71 return dis[m];
72 }
73
74 int main() {
75 in(n); in(m); in(k); in(_e);
76 int u,v,w;
77 for(int i = 1;i <= _e; ++i) {
78 in(u); in(v); in(w);
79 add(u,v,w); add(v,u,w);
80 }
81 in(d);
82 for(int i = 1;i <= d; ++i) {
83 int p,a,b;
84 in(p); in(a); in(b);
85 for(int j = a;j <= b; ++j) cls[p][j] = 1;
86 }
87 for(int i = 1;i <= n; ++i) {
88 for(int j = i;j <= n; ++j) {
89 low[i][j] = dijkstra(i,j);
90 if(low[i][j] > 0x3f3f3f3f) low[i][j] = 0x3f3f3f3f;
91 }
92 }
93 memset(f,0x3f,sizeof(f));
94 f[0] = -k;
95 for(int i = 1;i <= n; ++i) {
96 for(int j = 0;j < i; ++j) {
97 f[i] = min(f[i],f[j]+1ll*(i-j)*low[j+1][i]+1ll*k);
98 }
99 }
100 out(f[n]);
101 return 0;
102 }