P1772 [ZJOI2006]物流运输

流过昼夜 提交于 2019-11-27 08:29:14

${\color{cyan}{>>Question}}$

上古省选

最短路+$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 }

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!