上古省选
最短路+$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 }