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
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
//前三天走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;
}
#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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现