随笔 - 141,  文章 - 0,  评论 - 0,  阅读 - 1437

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

这道题是一个DP,首先用SPFA预处理得到第i天到第j天的花费dp[i][j],再用DP解决,动态转移方程为f[i]=min{f[i],f[j]+dp[j+1][i]+k},下面是程序:
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
const int D=105,N=25,M=1305,INF=0x3f3f3f3f;
struct queue{
	int a[N],l,r;
	void clear(){
		l=0,r=1;
	}
	bool empty(){
		return l+1==r;
	}
	void push(int x){
		a[r]=x;
		r++;
		r%=N;
	}
	void pop(){
		l++;
		l%=N;
	}
	int front(){
		return a[(l+1)%N];
	}
}q;
struct edge{
	int v,w,next;
}a[M];
bool use[N][D],vis[N],flag[N];
int dis[N],head[N],dp[D][D],f[D],k;
void add(int u,int v,int w){
	k++;
	a[k].v=v;
	a[k].w=w;
	a[k].next=head[u];
	head[u]=k;
}
void SPFA(){
	q.clear();
	memset(dis,0x3f,sizeof(dis));
	q.push(1);
	vis[1]=1;
	dis[1]=0;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		vis[u]=0;
		int now=head[u];
		while(now){
			int &v=a[now].v,&w=a[now].w;
			if(!flag[v]&&dis[u]+w<dis[v]){
				dis[v]=dis[u]+w;
				if(!vis[v]){
					q.push(v);
					vis[v]=1;
				}
			}
			now=a[now].next;
		}
	}
}
int main(){
	int d,n,k,m,u,v,w,i,j;
	scanf("%d%d%d%d",&d,&n,&k,&m);
	while(m--){
		scanf("%d%d%d",&u,&v,&w);
		add(u,v,w);
		add(v,u,w);
	}
	scanf("%d",&m);
	while(m--){
		scanf("%d%d%d",&w,&u,&v);
		for(;u<=v;u++){
			use[w][u]=1;
		}
	}
	for(u=1;u<=d;u++){
		for(v=u;v<=d;v++){
			memset(flag,0,sizeof(flag));
			for(i=1;i<=n;i++){
				for(j=u;j<=v;j++){
					flag[i]|=use[i][j];
				}
			}
			SPFA();
			dp[u][v]=dis[n];
			if(dp[u][v]!=INF){
				dp[u][v]*=v-u+1;
			}
		}
		f[u]=dp[1][u];
	}
	for(i=2;i<=d;i++){
		for(j=1;j<=i;j++){
			f[i]=min(f[i],f[j]+dp[j+1][i]+k);
		}
	}
	printf("%d\n",f[d]);
	return 0;
}

posted on   TLECODE  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示