bzoj1003物流运输
题意:有n天,m个点,每天要从1走到m,一些点有些时段不能到达,保证每天必有一条路能到m,每次更换路线花费k,求最少需要多少花费
此题数据范围很小,随便乱搞。
先跑一个n^2的spfa,求出cost[i][j](第i天到第j天每天的最小花费)
再一个dp就完了:
f[i]=min(f[i],f[j]+cost[j+1][i]*(i-j)+k);
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <queue> 5 using namespace std; 6 struct edge { 7 int v,next,w; 8 }e[2005]; 9 int k=1,n,m,E,d,kk; 10 int tim[25][105],avl[25],dis[25],vis[105],head[2005],f[105],cost[105][105]; 11 void adde(int u,int v,int w) { 12 e[k].v=v;e[k].w=w;e[k].next=head[u];head[u]=k++; 13 } 14 queue <int> q; 15 int spfa(int x,int y) { 16 memset(dis,63,sizeof(dis)); 17 memset(avl,0,sizeof(avl)); 18 memset(vis,0,sizeof(vis)); 19 for (int i=1;i<=m;i++) 20 for (int j=x;j<=y;j++) 21 if (tim[i][j]) avl[i]=1; 22 q.push(1);vis[1]=1;dis[1]=0; 23 while (!q.empty()) { 24 int u=q.front();q.pop();vis[u]=0; 25 for (int i=head[u];~i;i=e[i].next) { 26 int v=e[i].v; 27 if (!avl[v]&&dis[v]>dis[u]+e[i].w) { 28 dis[v]=dis[u]+e[i].w; 29 if (!vis[v]) { 30 q.push(v);vis[v]=1; 31 } 32 } 33 } 34 } 35 return dis[m]; 36 } 37 38 int main() 39 { 40 memset(head,-1,sizeof(head)); 41 memset(f,63,sizeof(f)); 42 f[0]=0; 43 scanf("%d%d%d%d",&n,&m,&kk,&E); 44 for (int i=1,a,b,c;i<=E;i++) { 45 scanf("%d%d%d",&a,&b,&c); 46 adde(a,b,c);adde(b,a,c); 47 } 48 scanf("%d",&d); 49 for (int i=1,p,a,b;i<=d;i++) { 50 scanf("%d%d%d",&p,&a,&b); 51 for (int j=a;j<=b;j++) tim[p][j]=1; 52 } 53 for (int i=1;i<=n;i++) 54 for (int j=1;j<=n;j++) 55 cost[i][j]=spfa(i,j); 56 for (int i=1;i<=n;i++) 57 for (int j=0;j<i;j++) 58 if(cost[j+1][i]!=0x3f3f3f3f) 59 f[i]=min(f[i],f[j]+cost[j+1][i]*(i-j)+kk); 60 printf("%d\n",f[n]-kk); 61 return 0; 62 }