【PAT1018】 Public Bike Management 单源最短路径路径记录回溯

2024-04-05 06:18

本文主要是介绍【PAT1018】 Public Bike Management 单源最短路径路径记录回溯,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1018. Public Bike Management (30)

时间限制
400 ms
内存限制
32000 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

There is a public bike service in Hangzhou City which provides great convenience to the tourists from all over the world. One may rent a bike at any station and return it to any other stations in the city.

The Public Bike Management Center (PBMC) keeps monitoring the real-time capacity of all the stations. A station is said to be in perfect condition if it is exactly half-full. If a station is full or empty, PBMC will collect or send bikes to adjust the condition of that station to perfect. And more, all the stations on the way will be adjusted as well.

When a problem station is reported, PBMC will always choose the shortest path to reach that station. If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.


Figure 1

Figure 1 illustrates an example. The stations are represented by vertices and the roads correspond to the edges. The number on an edge is the time taken to reach one end station from another. The number written inside a vertex S is the current number of bikes stored at S. Given that the maximum capacity of each station is 10. To solve the problem at S3, we have 2 different shortest paths:

1. PBMC -> S1 -> S3. In this case, 4 bikes must be sent from PBMC, because we can collect 1 bike from S1 and then take 5 bikes to S3, so that both stations will be in perfect conditions.

2. PBMC -> S2 -> S3. This path requires the same time as path 1, but only 3 bikes sent from PBMC and hence is the one that will be chosen.

Input Specification:

Each input file contains one test case. For each case, the first line contains 4 numbers: Cmax (<= 100), always an even number, is the maximum capacity of each station; N (<= 500), the total number of stations; Sp, the index of the problem station (the stations are numbered from 1 to N, and PBMC is represented by the vertex 0); and M, the number of roads. The second line contains N non-negative numbers Ci (i=1,...N) where each Ci is the current number of bikes at Si respectively. Then M lines follow, each contains 3 numbers: Si, Sj, and Tij which describe the time Tij taken to move betwen stations Si and Sj. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print your results in one line. First output the number of bikes that PBMC must send. Then after one space, output the path in the format: 0->S1->...->Sp. Finally after another space, output the number of bikes that we must take back to PBMC after the condition of Sp is adjusted to perfect.

Note that if such a path is not unique, output the one that requires minimum number of bikes that we must take back to PBMC. The judge's data guarantee that such a path is unique.

Sample Input:
10 3 3 5
6 7 0
0 1 1
0 2 1
0 3 3
1 3 1
2 3 1
Sample Output:
3 0->2->3 0
题意:

给一张图, 每个node都代表一个杭州的一个借或者还自行车站点, node上的值表示当前这个站点拥有多少量自行车, 每条边表示两个站点之间要花多少时间从一个站点到另一个站点, 给定一个有问题的站点, 求出从控制中心(PBMC)到该站点的最短路径并且使得带出去以及拿回来的自行车的数量最少.

分析:

①用最短路径算法(比如迪杰斯特拉)得到从PBMC到问题站点的所有最短路径;

②在Dijstra算法中,记录下每个节点的最优路径的上一节点,若有多个则全部记录下来;

③根据要求(带来最少带回最少),从目标节点的多个相同最短路径中找到最满足要求的一个;

④根据路径中记录的上一节点,进行回溯,直到根节点结束。

代码:

#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <stack>
using namespace std;//此代码使用前,需删除下面两行+后面的system("PAUSE")
ifstream fin("in.txt");
#define cin fin
#define MAXNUM 501
int curNum[MAXNUM]={0};			//每个station的自行车数量
int link[MAXNUM][MAXNUM]={0};
int minSumPath[MAXNUM]={0};			//达到每个station的最短路径长度
bool visited[MAXNUM]={false};
const int INF = 0x7fffffff;struct LastNode{int lastid;		//上一个节点int bikeSum;	//到当下的车辆总数int staCount;	//到当下的站点总数LastNode(int l,int b,int s){lastid=l;bikeSum=b;staCount=s;}
};vector<LastNode>  vec[MAXNUM];int c,n,s,m;void push(int target,int dataid){			//把dataid节点的统计数据导入到target节点for(int i=0;i<vec[dataid].size();i++){vec[target].push_back(LastNode(dataid,vec[dataid][i].bikeSum+curNum[target],vec[dataid][i].staCount+1));}
}void Dij(int source,int target){int cen = source;vec[0].push_back(LastNode(-1,0,0));int min,minIndex,newSumPath;while(1){visited[cen]=true;min = INF;for(int i=1;i<=n;i++){if(visited[i])continue;if(link[cen][i]!=0){newSumPath = minSumPath[cen]+link[cen][i];if(minSumPath[i]==0 || minSumPath[i]>newSumPath){		//有更小路径,更新minSumPath[i] = newSumPath;vec[i].clear();				//先清空vector再导入push(i,cen);}else if(minSumPath[i] == newSumPath){		//路径相等,添加push(i,cen);				//再原有数据基础上添加}}if(min > minSumPath[i] && minSumPath[i]!=0){min = minSumPath[i];minIndex = i;}}if(minIndex == target){		//如果找到目标节点,直接跳出循环break;}cen = minIndex;		}
}stack<int> handleIndex(int index){		//根据目标节点回溯到0号节点,将路径存储在stack中stack<int> res;int id = index;int cen = s;int staCount,bikeSum;int i;while(1){staCount = vec[cen][id].staCount-1;bikeSum = vec[cen][id].bikeSum - curNum[cen]; res.push(cen);cen = vec[cen][id].lastid;if(cen == -1)break;			//回溯到根节点 则跳出循环for(i=0;i<vec[cen].size();i++){if(vec[cen][i].staCount == staCount && vec[cen][i].bikeSum == bikeSum){		//看上一个节点的哪条数据满足条件id = i;break;}}}return res;
}int main()
{cin>>c>>n>>s>>m;if(n==0 || s==0){cout<<"0 0 0"<<endl;return 0;}int i;for(i=0;i<n;i++)cin>>curNum[i+1];int a,b;for(i=0;i<m;i++){cin>>a>>b;cin>>link[a][b];link[b][a]=link[a][b];}Dij(0,s);int plusZero = INF;int plusIndex = -1;int minusZero = -1000000;int minusIndex = -1;int index = -1;int need;			//需要带来的车辆数vector<LastNode> tt = vec[s];for(i=0;i< tt.size();i++){			//在目标节点 所有相同的最短路径中 找带来最少 带回最少的路径下标need = tt[i].staCount*c/2 - tt[i].bikeSum;if(need > 0){if(need < plusZero){plusZero = need;plusIndex = i;}}else if(need < 0){if(need > minusZero){minusZero = need;minusIndex = i;}}else{index = i;}}stack<int> res;			int come,back;if(index != -1){res = handleIndex(index);		//根据目标节点回溯到0号节点come = 0;back = 0;}else if(plusIndex != -1){res = handleIndex(plusIndex);come = plusZero;back = 0;}else{res = handleIndex(minusIndex);come = 0;back = 0-minusZero;}cout<<come<<' ';cout<<res.top();		//输出路径res.pop();while(!res.empty()){cout<<"->"<<res.top();res.pop();}cout<<" "<<back<<endl;system( "PAUSE");return 0;
}

结果:

测试点 结果 用时(ms) 内存(kB) 得分/满分
0 答案正确 2 380 12/12
1 答案正确 2 372 2/2
2 答案正确 2 376 2/2
3 答案正确 2 376 2/2
4 答案正确 1 380 2/2
5 答案错误 2 256 0/2
6 答案正确 2 376 2/2
7 答案错误 2 376 0/3
8 答案正确 2 376 2/2
9 答案正确 5 1404 1/1

还有两个Case不过,没发现原因,就先放这里吧。

这篇关于【PAT1018】 Public Bike Management 单源最短路径路径记录回溯的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877832

相关文章

Python获取中国节假日数据记录入JSON文件

《Python获取中国节假日数据记录入JSON文件》项目系统内置的日历应用为了提升用户体验,特别设置了在调休日期显示“休”的UI图标功能,那么问题是这些调休数据从哪里来呢?我尝试一种更为智能的方法:P... 目录节假日数据获取存入jsON文件节假日数据读取封装完整代码项目系统内置的日历应用为了提升用户体验,

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

MySQL INSERT语句实现当记录不存在时插入的几种方法

《MySQLINSERT语句实现当记录不存在时插入的几种方法》MySQL的INSERT语句是用于向数据库表中插入新记录的关键命令,下面:本文主要介绍MySQLINSERT语句实现当记录不存在时... 目录使用 INSERT IGNORE使用 ON DUPLICATE KEY UPDATE使用 REPLACE

Python 中的异步与同步深度解析(实践记录)

《Python中的异步与同步深度解析(实践记录)》在Python编程世界里,异步和同步的概念是理解程序执行流程和性能优化的关键,这篇文章将带你深入了解它们的差异,以及阻塞和非阻塞的特性,同时通过实际... 目录python中的异步与同步:深度解析与实践异步与同步的定义异步同步阻塞与非阻塞的概念阻塞非阻塞同步

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

Linux修改pip和conda缓存路径的几种方法

《Linux修改pip和conda缓存路径的几种方法》在Python生态中,pip和conda是两种常见的软件包管理工具,它们在安装、更新和卸载软件包时都会使用缓存来提高效率,适当地修改它们的缓存路径... 目录一、pip 和 conda 的缓存机制1. pip 的缓存机制默认缓存路径2. conda 的缓

Spring Boot中定时任务Cron表达式的终极指南最佳实践记录

《SpringBoot中定时任务Cron表达式的终极指南最佳实践记录》本文详细介绍了SpringBoot中定时任务的实现方法,特别是Cron表达式的使用技巧和高级用法,从基础语法到复杂场景,从快速启... 目录一、Cron表达式基础1.1 Cron表达式结构1.2 核心语法规则二、Spring Boot中定

Windows系统下如何查找JDK的安装路径

《Windows系统下如何查找JDK的安装路径》:本文主要介绍Windows系统下如何查找JDK的安装路径,文中介绍了三种方法,分别是通过命令行检查、使用verbose选项查找jre目录、以及查看... 目录一、确认是否安装了JDK二、查找路径三、另外一种方式如果很久之前安装了JDK,或者在别人的电脑上,想

国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)

《国内环境搭建私有知识问答库踩坑记录(ollama+deepseek+ragflow)》本文给大家利用deepseek模型搭建私有知识问答库的详细步骤和遇到的问题及解决办法,感兴趣的朋友一起看看吧... 目录1. 第1步大家在安装完ollama后,需要到系统环境变量中添加两个变量2. 第3步 “在cmd中

Python中Windows和macOS文件路径格式不一致的解决方法

《Python中Windows和macOS文件路径格式不一致的解决方法》在Python中,Windows和macOS的文件路径字符串格式不一致主要体现在路径分隔符上,这种差异可能导致跨平台代码在处理文... 目录方法 1:使用 os.path 模块方法 2:使用 pathlib 模块(推荐)方法 3:统一使