bzoj 1003

Description

  物流公司要把一批货物从码头A运到码头B。由于货物量比较大,需要n天才能运完。货物运输过程中一般要转

停好几个码头。物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪。由于各种

因素的存在,有的时候某个码头会无法装卸货物。这时候就必须修改运输路线,让货物能够按时到达目的地。但是

修改路线是一件十分麻烦的事情,会带来额外的成本。因此物流公司希望能够订一个n天的运输计划,使得总成本

尽可能地小。

Input

  第一行是四个整数n(1<=n<=100)、m(1<=m<=20)、K和e。n表示货物运输所需天数,m表示码头总数,K表示

每次修改运输路线所需成本。接下来e行每行是一条航线描述,包括了三个整数,依次表示航线连接的两个码头编

号以及航线长度(>0)。其中码头A编号为1,码头B编号为m。单位长度的运输费用为1。航线是双向的。再接下来

一行是一个整数d,后面的d行每行是三个整数P( 1 < P < m)、a、b(1< = a < = b < = n)。表示编号为P的码

头从第a天到第b天无法装卸货物(含头尾)。同一个码头有可能在多个时间段内不可用。但任何时间都存在至少一

条从码头A到码头B的运输路线。

Output

  包括了一个整数表示最小的总成本。总成本=n天运输路线长度之和+K*改变运输路线的次数。

Sample Input

5 5 10 8

1 2 1

1 3 3

1 4 2

2 3 2

2 4 4

3 4 1

3 5 2

4 5 2

4

2 2 3

3 1 1

3 3 3

4 4 5

Sample Output

32

//前三天走1-4-5,后两天走1-3-5,这样总成本为(2+2)*3+(3+2)*2+10=32

思路:关键是怎么加上改变时候的价值。t[i][j]表示第i天到第j天的最短路,f[i]表示前i天最短路,我们可以假设发生过改变,t[i][j]=min(t[i][j],t[i][kk]+k+t[kk+1][j]*(j-kk)).

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4
 5 const int N=24;
 6
 7 struct node{
 8     int to,next,val;
 9 }e[801];
10 int tot,head[N];
11
12 int vis[N],dis[N];
13 int a[102][102];
14 int n,m,k,E;
15
16 void init(){
17     tot=0;
18     memset(head,-1,sizeof(head));
19 }
20
21 void add(int x,int y,int z){
22     e[tot].to=y;e[tot].next=head[x];e[tot].val=z;head[x]=tot++;
23 }
24
25 struct point{
26     int id,vval;
27     point(int xx,int yy){
28         id=xx;vval=yy;
29     }
30     bool operator <(const point &x) const{
31         return vval>x.vval;
32     }
33 };
34
35 bool block[22];
36 ll t[102][102];
37
38 int hh(int xxx,int yyy){
39     memset(vis,0,sizeof(vis));
40     memset(dis,127/3,sizeof(dis));
41     dis[1]=0;
42     priority_queue<point >p;
43     p.push(point(1,0));
44     memset(block,0,sizeof(block));
45     for(int i=xxx;i<=yyy;i++)
46         for(int j=1;j<=m;j++) if(a[i][j]) block[j]=1;
47     while(!p.empty()){
48         point xx=p.top();
49         p.pop();
50         if(vis[xx.id]) continue;
51         vis[xx.id]=1;
52         for(int i=head[xx.id];i!=-1;i=e[i].next){
53             int v=e[i].to;
54             if(!vis[v]&&!block[v]&&xx.vval+e[i].val<dis[v]){
55                 dis[v]=xx.vval+e[i].val;
56                 p.push(point(v,dis[v]));
57             }
58         }
59     }
60     return dis[m];
61 }
62
63 ll f[102];
64
65 void dp()
66 {
67     for(int i=1;i<=n;i++)
68     {
69        f[i]=(long long)t[1][i]*i;
70        for(int j=0;j<i;j++)
71           f[i]=min(f[i],f[j]+k+t[j+1][i]*(i-j));
72     }
73 }
74
75 int main(){
76     scanf("%d%d%d%d",&n,&m,&k,&E);
77     init();
78     int x,y,z;
79     for(int i=1;i<=E;i++){
80         scanf("%d%d%d",&x,&y,&z);
81         add(x,y,z);
82         add(y,x,z);
83     }
84     int q;
85     scanf("%d",&q);
86     for(int i=1;i<=q;i++){
87         scanf("%d%d%d",&x,&y,&z);
88         for(int j=y;j<=z;j++) a[j][x]=1;
89     }
90     for(int i=1;i<=n;i++){
91         for(int j=1;j<=n;j++) {
92                 t[i][j]=hh(i,j);
93         }
94     }
95     dp();
96     cout<<f[n]<<endl;
97 }
时间: 2024-10-11 21:43:57

bzoj 1003的相关文章

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 物流运输trans(最短路)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1003 思路:m个点e条边n天.给出每条边的权值以及有些点有些天不能走.对于某连续的两天i和i+1,若两天从起点到终点选择的路径不同需要额外代价K.求最小的总代价:ans=sum(每天的代价)+K*改变的次数.每天的代价定义为这一天s到t选择的路径的长度. 思路:令cost[i][j]表示从第i天 到第j天选择一条路径的最短路,f[i]表示前i天的总代价,则f[i]=min(f[j]+c

bzoj 1003 最短路+dp

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

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<algorit

BZOJ 1003 dp+最短路

1003: [ZJOI2006]物流运输 题意:m个码头,从码头1到码头m,连续n天都要运送货物.每一天的花费是总路线长度大小,但如果和前一天的路线不一样,要另处加上k元花费.而且有些码头有些天不能用,问这n天的最小费用. tags:菜鸡一开始真没想到是dp 求n天时最小花费,就要想到以天数为阶段进行规划.dp[i][j]表示第i天到第j天走同一条路线的花费,则f[i]=min( f[i], f[j]+dp[j+1][i]+k ). #include<bits/stdc++.h> using

洛谷 P2144 BZOJ 1003 [FJOI2007]轮状病毒

题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间的信息通道,如图1. n轮状病毒的产生规律是在n轮状基中删除若干边,使各原子之间有唯一一条信息通道.例如,共有16个不同的3轮状病毒,入图2所示. 给定n(N<=100),编程计算有多少个不同的n轮状病毒. 输入输出格式 输入格式: 第一行有1个正整数n. 输出格式: 将编程计算出的不同的n轮状病毒数输出 输入输出样例 输入样例#1: 3

BZOJ 1003 物流运输trans dijstra+dp

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

BZOJ 1003 物流运输 (动态规划 SPFA 最短路)

1003: [ZJOI2006]物流运输 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 5590 Solved: 2293 [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)

挖坑,日常划水. 从BZOJ上的AC人数来看这题确实不难,但做这种题的常见思路让小C决定还是mark一下. Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地.但是修改路线是一件十分麻烦的事情,会带来额外的成本.因此物流公司希望能够订