BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)

http://www.lydsy.com/JudgeOnline/problem.php?id=1003

题意:

思路:

首先用spfa计算一下任意两天之内的最短路,dis[a][b]表示的就是在第a天~第b天从1到m的最短路。

接下来就是dp了,f[i]表示前i天的最小代价,那么状态转移方程就是:

f[i]=min(f[i],f[j]+dis[j+1][i]*(i-j)+k)

注意:边界条件f[0]=-k!

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 #include<set>
 12 using namespace std;
 13 typedef long long ll;
 14 typedef pair<int,ll> pll;
 15 const int INF = 0x3f3f3f3f;
 16 const int maxn=1000+5;
 17
 18 int n, m, k, t;
 19 int tot;
 20 int head[maxn];
 21 int flag[maxn][maxn];
 22 int dis[maxn][maxn];
 23 int d[maxn];
 24 int inq[maxn];
 25 ll f[maxn];
 26
 27 struct node
 28 {
 29     int v, w;
 30     int next;
 31 }e[maxn];
 32
 33 void AddEdge(int u, int v, int w)
 34 {
 35     e[tot].v=v;
 36     e[tot].w=w;
 37     e[tot].next=head[u];
 38     head[u]=tot++;
 39 }
 40
 41 void spfa(int s, int a, int b)
 42 {
 43     for(int i=1;i<=m;i++)   d[i]=INF;
 44     queue<int> Q;
 45     Q.push(s);
 46     d[s]=0;
 47     while(!Q.empty())
 48     {
 49         int u=Q.front(); inq[u]=0; Q.pop();
 50         for(int i=head[u];i!=-1;i=e[i].next)
 51         {
 52             int v=e[i].v;
 53             if(flag[v][b]-flag[v][a-1]>0)  continue;
 54             if(d[v]>d[u]+e[i].w)
 55             {
 56                 d[v]=d[u]+e[i].w;
 57                 if(!inq[v])
 58                 {
 59                     Q.push(v);
 60                     inq[v]=1;
 61                 }
 62             }
 63         }
 64     }
 65     dis[a][b]=d[m];
 66 }
 67
 68 int main()
 69 {
 70     //freopen("in.txt","r",stdin);
 71     while(~scanf("%d%d%d%d",&n,&m,&k,&t))
 72     {
 73         tot=0;
 74         memset(head,-1,sizeof(head));
 75         memset(flag,0,sizeof(flag));
 76         for(int i=0;i<t;i++)
 77         {
 78             int u,v,w;
 79             scanf("%d%d%d",&u,&v,&w);
 80             AddEdge(u,v,w);
 81             AddEdge(v,u,w);
 82         }
 83
 84         scanf("%d",&t);
 85         while(t--)
 86         {
 87             int x,a,b;
 88             scanf("%d%d%d",&x,&a,&b);
 89             for(int i=a;i<=b;i++)  flag[x][i]=1;
 90         }
 91
 92         for(int i=1;i<=m;i++)
 93             for(int j=1;j<=n;j++)  flag[i][j]+=flag[i][j-1];  //用前缀和可以快速判断i~j天是否可用
 94
 95         for(int i=1;i<=n;i++)
 96             for(int j=i;j<=n;j++)  spfa(1,i,j);
 97
 98         f[0] = -k;  //注意边界条件
 99         for(int i = 1; i <= n; i ++)
100         {
101             f[i] = INF;
102             for(int j = 0; j < i; j++)
103             f[i] = min(f[i], f[j] + 1LL*dis[j+1][i]*(i-j) + k);
104         }
105         printf("%d\n",f[n]);
106     }
107     return 0;
108 }
时间: 2024-10-14 01:10:59

BZOJ 1003: [ZJOI2006]物流运输(spfa+dp)的相关文章

BZOJ 1003: [ZJOI2006]物流运输trans DP+最短路

Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地.但是修改路线是一件十分麻烦的事情,会带来额外的成本.因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小. Input 第一行是四个整数n(1<=n<=100).m(1&

BZOJ 1003: [ZJOI2006]物流运输trans

二次联通门 : BZOJ 1003: [ZJOI2006]物流运输trans /* BZOJ 1003: [ZJOI2006]物流运输trans Spfa + Dp Spfa预处理出i到j天的最小花费 然后N^2 dp即可 */ #include <cstdio> #include <iostream> #include <cstring> #include <queue> #define INF 1e6 const int BUF = 12312313;

bzoj 1003: [ZJOI2006]物流运输trans 最短路+dp

题目链接 1003: [ZJOI2006]物流运输trans Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5246  Solved: 2157[Submit][Status][Discuss] Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无

bzoj 1003 [ZJOI2006]物流运输(最短路+dp)

[ZJOI2006]物流运输 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8973  Solved: 3839[Submit][Status][Discuss] Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输

BZOJ 1003: [ZJOI2006]物流运输trans SPFA+DP

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1003 题解: dp就好,令dp[i]表示第i天的答案,那么dp[i]=min{Cost(1,i),Cost(j+1,i)+dp[j]+K},其中Cost(i,j)表示从i到j都用同一种方案.这种dp和划分问题很类似. 代码: #include<iostream> #include<cstring> #include<algorithm> #include<

BZOJ 1003 ZJOI2006 物流运输trans 动态规划+SPFA

题目大意:给定一个无向图,运输n天,其中有些天有些点不能走,更换路线代价为k,求代价总和 首先令cost[i][j]为第i天到第j天都走同一路线的最小花销 这个用SPFA处理 然后就是动规的问题了 令f[i]为1~i天的最小花销 则f[i]=min{ f[j]+cost[j+1][i]+k } ( 0<=j<i ) 注意m和n别写反 乘天数之前要特判是不是正无穷 #include<cstdio> #include<cstring> #include<iostrea

BZOJ.1003.[ZJOI2006]物流运输(DP 最短路Dijkstra)

题目链接 容易看出是个最短路+DP.既然答案和天数有关,那么就令f[i]表示前i天最小成本. 这个转移很好想: f[i]=min(f[i],f[j]+cost(j+1,i)+K),cost(j+1,i)即第j+1天到第i天(使用同一道路)所需花费,即最短路,这个可以预处理出来. 注意是否可行的判断. //880kb 88ms //好像很吉利啊 #include <queue> #include <cstdio> #include <cctype> #include &l

[bzoj]1003: [ZJOI2006]物流运输

Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地.但是修改路线是一件十分麻烦的事情,会带来额外的成本.因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小. Input 第一行是四个整数n(1<=n<=100).m(1&

1003: [ZJOI2006]物流运输 最短路+dp

https://www.lydsy.com/JudgeOnline/problem.php?id=1003 数据范围很小,怎么瞎搞都行,n方dp,然后跑出最短路暴力转移,需要注意的是不能使用的可能有多个区间 /************************************************************** Problem: 1003 User: walfy Language: C++ Result: Accepted Time:180 ms Memory:1400 k