【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实现矢量路径的压缩、解压与可视化

《使用Python实现矢量路径的压缩、解压与可视化》在图形设计和Web开发中,矢量路径数据的高效存储与传输至关重要,本文将通过一个Python示例,展示如何将复杂的矢量路径命令序列压缩为JSON格式,... 目录引言核心功能概述1. 路径命令解析2. 路径数据压缩3. 路径数据解压4. 可视化代码实现详解1

Java使用SLF4J记录不同级别日志的示例详解

《Java使用SLF4J记录不同级别日志的示例详解》SLF4J是一个简单的日志门面,它允许在运行时选择不同的日志实现,这篇文章主要为大家详细介绍了如何使用SLF4J记录不同级别日志,感兴趣的可以了解下... 目录一、SLF4J简介二、添加依赖三、配置Logback四、记录不同级别的日志五、总结一、SLF4J

在Spring Boot中浅尝内存泄漏的实战记录

《在SpringBoot中浅尝内存泄漏的实战记录》本文给大家分享在SpringBoot中浅尝内存泄漏的实战记录,结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录使用静态集合持有对象引用,阻止GC回收关键点:可执行代码:验证:1,运行程序(启动时添加JVM参数限制堆大小):2,访问 htt

MySQL 中查询 VARCHAR 类型 JSON 数据的问题记录

《MySQL中查询VARCHAR类型JSON数据的问题记录》在数据库设计中,有时我们会将JSON数据存储在VARCHAR或TEXT类型字段中,本文将详细介绍如何在MySQL中有效查询存储为V... 目录一、问题背景二、mysql jsON 函数2.1 常用 JSON 函数三、查询示例3.1 基本查询3.2

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 的缓