PAT甲级1018 Public Bike Management (C++)

本题翻译:
题目给出四个数字,分别是Cmax(每站最大的自行车容量),N(总站数),Sp(问题站),M(路数)
第二行是站点的自行车数量
接下来的N行是站点x,站点y,两个站点的距离。
为了到达问题站,将问题占的自行车数量调整为Cmax/2,并且把顺路的站点自行车数量都调整为Cmax/2,问要从0号拿多少自行车,或者带回多少自行车。最短距离优先于拿自行车的数量优先于带回自行车的数量。也就是说,距离越短越好,距离相同的情况下,拿自行车数量越好越好,如果还是一样,那就带回的自行车数量越少越好。
本题思路:
利用深度搜索进行图的遍历,寻找最短路径,顺带把自行车带回或拿自行车的数量计算一下,并存储最短路径的站点。
详细代码样例:

#include <bits/stdc++.h>
using namespace std;
//整体题意就是 自行车找最最短路程,最短路程找要送的车最少 如果还是一样 则带走的车最少
int Cmax,N,Sp,M;// 每站最大的自行车容量 总站数 问题站 路数
//先把数据存了
int bike[501];
int dis[501][501];//存两个站的距离 
vector <int> v[501];//存邻居 
int mindis[501];//最短距离 
vector <int> path;//记录遍历的站,存起来,后面输出要用 
int minsend;//送出的最少车 
int mintake;//带走的最少车 
int mindistance=999999;
vector <int> final_ans;
int ss=0;
void dfs(int curstation,int curlen,int cursend,int curtake){//当前站点,当前距离,当前送来的车要多少 当前送走的车要多少
	if(curlen>mindis[curstation]) return;//如果当前距离超过了之前的距离,或者形成了环路,及时止损 
	path.emplace_back(curstation);//存入当前的站点 
	if(curstation==Sp){//如果到达了目的地 
		if(curlen<mindistance||(curlen==mindistance&&cursend<minsend)||(curlen==mindistance&&cursend==minsend&&curtake<mintake)){//三种情况,要么符合最短路程||都是最短路程看送车最少 ||前两者一样带走的车最少,三个条件满足之一即可 
		//把成功的路径 赋值 
			mindistance=curlen;
			minsend=cursend;
			mintake=curtake;
			final_ans = path;
		}
	}else{//没有达到目的地 
		if(curlen<mindis[curstation]){//先判断下这条路是不是比上次的短,如果是,更新 
			mindis[curstation] = curlen;
		}
		for(int j:v[curstation]){//int i=0;i<v[curstation].size();i++ 遍历当前站点的所有邻居 

			if(curtake+bike[j]<Cmax/2){//这个时候判断送车或带回车的关系,如果加上拿来的车还不够那么说明还要送点车来 
				dfs(j,curlen+dis[curstation][j],Cmax/2+cursend-curtake-bike[j],0);
			}else{
				dfs(j,curlen+dis[curstation][j],cursend,curtake+bike[j]-Cmax/2);//否则就是这条路车多了,送走 
			}
		}
	} 
	path.pop_back();//有进有出,等于回溯 
	
}
int main(){
	//数据的存储 
	int i,j,k;
	cin>>Cmax>>N>>Sp>>M;
	for(i=1;i<=N;i++){
		cin>>bike[i];//每个站点自行车的总数 
	}
	while(M--){//存入每个站点的邻居,站点与站点之间的距离 
		cin>>i>>j>>k;
		dis[i][j]=dis[j][i]=k;
		v[i].emplace_back(j);
		v[j].emplace_back(i); 
	}
	for(i=0;i<=N;i++) mindis[i]=999999;//未到之前,最短距离都是最大的,等待更新 

	dfs(0,0,0,0);//深搜
	//输出结果 
	cout<<minsend<<' ';
	cout<<final_ans[0];
	for(i=1;i<final_ans.size();i++){
		cout<<"->"<<final_ans[i];
	}
	cout<<' '<<mintake;
} 

在这里插入图片描述

本题难度还比较大,需要熟练掌握深搜,和上次1003的深搜类似,但这道题难度更加大,多了自行车的数量计算以及站点的存储。感谢b站的up主弄夫,太厉害啦!
up主的视频指路视频指路
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值