首页 > 代码库 > bzoj1003物流运输

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 }
View Code

 

bzoj1003物流运输