1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs
前言:
本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大orz,这里给出柳神的题解地址:https://blog.csdn.net/liuchuo/article/details/52316405
题意:
有一个租借自行车的系统由n个点组成,用户可以在这n个点任意一个点借车或者还车,每个点都遵循一个共同的上限c,这里我们称一个点的状态时完美的如果这个点的车的数量为c/2,(每个点由1~n标号),而我们的出发点为0点,整个系统每次会有一个sp点发出警报,说明这个sp点的自行车数量需要调整至c/2,让我们求的时从0点出发,找一条最短的路径到达sp,调整sp以及沿途的自行车数量都达到c/2,如果车的数量不够则需要从0点调出车,(这里调整的过程是不准往回的,且到达sp点为止,后面车多了前面车少了则还是需要从0点调配出来),如果此时车多了则可以带走供给后面的车使用,到达sp点后结束,如果由多的车则全部送回,本题求的是当有一个点sp报警的时候,在最短路径的基础上,最少需要从0点调配出多少车,如果路径不唯一则选择同时送最少的车回来的路径,输出整条路径和需要送出的车数和送回的车数
分析:
本题主要由两部分构成,①首先通过dijkstra求出从0点到sp点的最短路径,在求的过程中利用一个vector数组pre[i]保存在最短路径的基础上,到达i点的所有前驱节点(因为先只考虑最短路径的情况的话可能不止有一条从0->sp的路径是最短的,每个点自然也有可能有不止一个前驱点)②通过dfs尝试每一种从0->sp的路径,计算出这条路径需要多少车need和送回多少车back,在所有的路径中选择一条need最小的,如果有并列的话,选择back最小的
注意:
虽然做题的时候我也是差不多这么想的,但是对于如何存储下每一条具体的最短路径和计算这每一条最短路径下的need和back却难住了我...还是学艺不精,我炸了,这里提醒一下需要仔细观察dfs部分的代码,这里通过一个vector数组temppath存放了每一条路径,从sp点开始,一边dfs深搜到0点,同时也将沿途的点加入到temppath中,在到达0的同时,每次都在temppath中倒着将这一条道路记录了下来,每次用完一个点之后就删去最后一个点(就像是回溯的过程)
代码:
- 1 #include<iostream>
- 2 #include<algorithm>
- 3 #include<vector>
- 4 #include<string.h>
- 5 using namespace std;
- 6
- 7 const int inf = 0x3f3f3f3f;
- 8 int cmax, n, sp, m;
- 9 int minNeed = inf, minBack = inf;
- 10 int e[510][510], dis[510], weight[510];
- 11 bool vis[510];
- 12 vector<int> pre[510], path, temppath;
- 13
- 14 void dfs(int v){
- 15 temppath.push_back(v);
- 16 if(v == 0){
- 17 int need = 0, back = 0;
- 18 for(int i = temppath.size()-1; i >= 0; i--){
- 19 int id = temppath[i];
- 20 if(weight[id] > 0){
- 21 back += weight[id];
- 22 }else{
- 23 if(back > (0 - weight[id])){//需要车且有足够的车
- 24 back += weight[id];
- 25 }else{ //需要车但是车不够需要派出
- 26 need += ((0 - weight[id]) - back);
- 27 back = 0;
- 28 }
- 29 }
- 30 }
- 31 if(need < minNeed){
- 32 minNeed = need;
- 33 minBack = back;
- 34 path = temppath;
- 35 }else if(need == minNeed && back < minBack){
- 36 minBack = back;
- 37 path = temppath;
- 38 }
- 39 temppath.pop_back();
- 40 return;
- 41 }
- 42 for(int i = 0; i < pre[v].size(); i++)
- 43 dfs(pre[v][i]); //往回找起点 0
- 44 temppath.pop_back();
- 45 }
- 46
- 47 int main(){
- 48 memset(e, inf, sizeof(e));
- 49 memset(dis, inf, sizeof(dis));
- 50 scanf("%d%d%d%d", &cmax, &n, &sp, &m);
- 51 for(int i = 1; i <= n; i++){
- 52 scanf("%d", &weight[i]);
- 53 weight[i] = weight[i] - cmax/2;
- 54 }
- 55 for(int i = 0; i < m; i++){
- 56 int a, b;
- 57 scanf("%d%d", &a, &b);
- 58 scanf("%d", &e[a][b]);
- 59 e[b][a] = e[a][b];
- 60 }
- 61 dis[0] = 0;
- 62 for(int i = 0; i <= n; i++){
- 63 int u = -1, minn = inf;
- 64 for(int j = 0; j <= n; j++){
- 65 if(vis[j] == 0 && dis[j] < minn){
- 66 minn = dis[j];
- 67 u = j;
- 68 }
- 69 }
- 70 if(u == -1) break;
- 71 vis[u] = 1;
- 72 for(int j = 0; j <= n; j++){
- 73 if(vis[j] == 0 && e[u][j] != inf){
- 74 if(dis[j] > dis[u] + e[u][j]){
- 75 dis[j] = dis[u] + e[u][j];
- 76 pre[j].clear();
- 77 pre[j].push_back(u);
- 78 }else if(dis[j] == dis[u] + e[u][j]){
- 79 pre[j].push_back(u);
- 80 }
- 81 }
- 82 }
- 83 }
- 84 dfs(sp);
- 85 printf("%d 0", minNeed);
- 86 for(int i = path.size()-2; i >= 0; i--){
- 87 printf("->%d", path[i]);
- 88 }
- 89 printf(" %d\n", minBack);
- 90 return 0;
- 91 }
1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs的更多相关文章
- PAT 甲级 1018 Public Bike Management (30 分)(dijstra+dfs,dfs记录路径,做了两天)
1018 Public Bike Management (30 分) There is a public bike service in Hangzhou City which provides ...
- 1018 Public Bike Management (30 分)
There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...
- 1018 Public Bike Management (30分) 思路分析 + 满分代码
题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...
- 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)
题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...
- 1018 Public Bike Management (30分) (迪杰斯特拉+dfs)
思路就是dijkstra找出最短路,dfs比较每一个最短路. dijkstra可以找出每个点的前一个点, 所以dfs搜索比较的时候怎么处理携带和带走的数量就是关键,考虑到这个携带和带走和路径顺序有关, ...
- 1018 Public Bike Management (30)(30 分)
时间限制400 ms 内存限制65536 kB 代码长度限制16000 B There is a public bike service in Hangzhou City which provides ...
- PAT Advanced 1018 Public Bike Management (30) [Dijkstra算法 + DFS]
题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...
- 1018. Public Bike Management (30)
时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue There is a public bike service i ...
- PAT A 1018. Public Bike Management (30)【最短路径】
https://www.patest.cn/contests/pat-a-practise/1018 先用Dijkstra算出最短路,然后二分答案来验证,顺便求出剩余最小,然后再从终点dfs回去求出路 ...
随机推荐
- Python排序函数用法
Python排序函数完美体现了Python语言的简洁性,对于List对象,我们可以直接调用sort()函数(这里称为"方法"更合适)来进行排序,而对于其他可迭代对象(如set,di ...
- 使用Swiper快速实现3D效果轮播
最近经常接到轮播图3D效果的需求, 特在此记录一下以备之后使用. 具体实现效果如下: 在这里介绍两种使用方式, 一种原生的html+php后端渲染, 一种是使用vue. 原生实现 引入 首先我们介绍原 ...
- DPSK通信系统的FPGA实现
之前接触过一些FPGA的相关知识,借着实现一个简单的DPSK系统,顺便复习和记录一下Verilog HDL的简单使用方法.准备直接用一张图展现DPSK的调制解调原理,再按照模块介绍Verilog的实现 ...
- 使用form表单上传文件
在使用form表单上传文件时候,input[type='file']是必然会用的,其中有一些小坑需要避免. 1.form的 enctype="multipart/form-data" ...
- Typora+Picgo+Gitee实现上传图片
下载picgo和node.js 百度网盘地址: 链接:https://pan.baidu.com/s/1QwbXn4vFuDfSFNOnZU5-Jg 取码:efgc 打开picgo,安装gitee-u ...
- 利用设计模式消除业务代码中的 if-else
准备工作:假设这样的一个业务场景:有一个自动开票的功能需要实现,在程序里面需要根据账单的类型执行对应的处理逻辑. 以下使用了 Lombok 简化代码!!! 账单类型枚举: /** * @author ...
- C# 如何查询字符串前面有几个0
有几个0 string t = "0001203"; int tLen = t.Length - t.TrimStart('0').Length; charAt方法 using S ...
- 算法竞赛入门经典第二版第一章习题-(练习Java和C++语法)
习题1-1 平均数(average) 输入三个整数,输出他们的平均值,保留三位小数 Java: package suanfa; import java.util.Scanner; public cla ...
- Solon 特性简集,相较于 Springboot 有什么区别?
Solon 是一个类似Springboot的微型开发框架,也是一个不基于Servlet的开发框架.项目从2018年启动以来,参考过大量前人作品:历时两年,3500多次的commit:内核保持0.1m的 ...
- pdf2swf 和pdf2html 使用命令详解
pdf2swf 将pdf文档转换为flash方式阅读,可以满足公式.图片的格式定义: pdf2htmlEX 将pdf文档转换为html方式阅读,有一下优点: 在HTML文件中精确显示原生文本 保持PD ...