bzoj 1003: [ZJOI2006]物流运输trans
这道题还算比较水。。
spfa预处理从第i天到第j天的可行最短路存为t[i][j],
然后直接dp。
f[i] 代表到第i天的最小费用
f[i] = min(f[i],min(t[1][i]*i,f[j]+k+t[j+1][i]*(i-j)))
1 /* 2 ID:zsy99021 3 PROB:bzoj1003 4 LANG:C++ 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <algorithm> 9 #include <cmath> 10 #include <iostream> 11 #include <fstream> 12 #include <ctime> 13 #define N 108 14 #define M 28 15 #define mid(l,r) ((l+r) >> 1) 16 #define INF 0x7ffffff 17 using namespace std; 18 19 long long n,t[N][N],m,k,e,head[M]; 20 long long f[N]; 21 bool flag[N][M]; 22 23 struct wulala 24 { 25 int node,next,dist; 26 }h[M*M]; 27 28 int spfa(int a,int b) 29 { 30 bool block[M],inq[M]; 31 int dis[M]; 32 int tail = 0,headd = 1,q[M*M]; 33 memset(block,0,sizeof(block)); 34 memset(inq,0,sizeof(inq)); 35 memset(q,0,sizeof(q)); 36 for (int i = 1;i <= m;i++) dis[i] = INF; 37 for (int i = a;i <= b;i++) 38 for (int j = 1;j <= m;j++) if (flag[i][j]) block[j] = true; 39 q[1] = 1; inq[1] = true; dis[1] = 0; 40 while(tail < headd) 41 { 42 int u = q[++tail]; 43 int c = head[u]; 44 while(c) 45 { 46 if (block[h[c].node]||dis[h[c].node] < dis[u] + h[c].dist) 47 { 48 c = h[c].next; 49 continue; 50 } 51 if (!inq[h[c].node]) q[++headd] = h[c].node; 52 dis[h[c].node] = dis[u] + h[c].dist; 53 inq[h[c].node] = true; 54 c = h[c].next; 55 } 56 inq[u] = false; 57 } 58 return(dis[m]); 59 } 60 61 void init() 62 { 63 memset(flag,0,sizeof(flag)); 64 scanf("%d%d%d%d",&n,&m,&k,&e); 65 for (int i = 1;i <= e;i++) 66 { 67 int x,y,z; 68 scanf("%d%d%d",&x,&y,&z); 69 h[2*i-1].node = y; 70 h[2*i].node = x; 71 h[2*i-1].dist = h[2*i].dist = z; 72 h[2*i-1].next = head[x]; 73 head[x] = 2 * i - 1; 74 h[2*i].next = head[y]; 75 head[y] = 2 * i; 76 } 77 int d; 78 scanf("%d",&d); 79 for (int i = 1;i <= d;i++) 80 { 81 int a,b,p; 82 scanf("%d%d%d",&p,&a,&b); 83 for (int j = a;j <= b;j++) flag[j][p] = true; 84 } 85 for (int i = 1;i <= n;i++) 86 for (int j = i;j <= n;j++) 87 t[i][j] = spfa(i,j); 88 } 89 90 void work() 91 { 92 memset(f,127,sizeof(f)); 93 for (int i = 1;i <= n;i++) f[0] = 0; 94 for (int i = 1;i <= n;i++) 95 for (int j = 0;j < i;j++) 96 f[i] = min(f[i],min(t[1][i]*i,f[j]+k+t[j+1][i]*(i-j))); 97 } 98 99 void debug() 100 { 101 for (int i = 1;i <= n;i++) 102 { 103 for (int j = 1;j <= n;j++) printf("%d ",t[i][j]); 104 printf("\n"); 105 } 106 } 107 108 int main() 109 { 110 init(); 111 // debug(); 112 work(); 113 printf("%d\n",f[n]); 114 return 0; 115 }