前言:

本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大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的更多相关文章

  1. 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 ...

  2. 1018 Public Bike Management (30 分)

    There is a public bike service in Hangzhou City which provides great convenience to the tourists fro ...

  3. 1018 Public Bike Management (30分) 思路分析 + 满分代码

    题目 There is a public bike service in Hangzhou City which provides great convenience to the tourists ...

  4. 【PAT甲级】1018 Public Bike Management (30 分)(SPFA,DFS)

    题意: 输入四个正整数C,N,S,M(c<=100,n<=500),分别表示每个自行车站的最大容量,车站个数,此次行动的终点站以及接下来的M行输入即通路.接下来输入一行N个正整数表示每个自 ...

  5. 1018 Public Bike Management (30分) (迪杰斯特拉+dfs)

    思路就是dijkstra找出最短路,dfs比较每一个最短路. dijkstra可以找出每个点的前一个点, 所以dfs搜索比较的时候怎么处理携带和带走的数量就是关键,考虑到这个携带和带走和路径顺序有关, ...

  6. 1018 Public Bike Management (30)(30 分)

    时间限制400 ms 内存限制65536 kB 代码长度限制16000 B There is a public bike service in Hangzhou City which provides ...

  7. 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 ...

  8. 1018. Public Bike Management (30)

    时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue There is a public bike service i ...

  9. PAT A 1018. Public Bike Management (30)【最短路径】

    https://www.patest.cn/contests/pat-a-practise/1018 先用Dijkstra算出最短路,然后二分答案来验证,顺便求出剩余最小,然后再从终点dfs回去求出路 ...

随机推荐

  1. 【题解】「CF1182B」Plus from Picture

    这是一道超级水的模拟 + 简单搜索. 说说思路: 先找到中心点,就是自己和上下左右都为 * 的. 上下左右上的所有 * 都删掉,然后再看看有没有多余的 * 如果有输出 NO 否则输出 YES. 比如说 ...

  2. 计算机语言与JAVA的发展

    计算机语言与JAVA的发展 第一代语言 2进制 第二代语言 汇编语言 解决人类无法读懂的问题 指令替代二进制 目前应用 逆向工程 机器人 病毒 第三代语言 摩尔定律 性能提升愈来愈慢 高级语言 面向过 ...

  3. 搭建docker registry私有镜像仓库

    搭建docker registry私有镜像仓库 一.安装docker-distribution yum install -y docker-distribution 安装完成后,启动服务: syste ...

  4. 珍藏的C语言编程系列教程

    本文有332个文字,大小约为2KB,预计阅读时间1分钟 这是本人珍藏的C语言.C++系列教程. 相信每个Coder的第一门编程语言就是C语言吧, 现在也依然很热门,不谈了.直接上链接,感兴趣的直接存, ...

  5. rhel 7 multipath服务启动报错

    配置多路径服务,启动多路径multipathd.service的时候出现下面报错: [root@rac2 ~]# systemctl status multipathd.service multipa ...

  6. Private jre vs Public jre

    今天说一下java环境构建中,jre相关的小知识点. private jre:一般是C:\Program Files\jdk1.8.0\jre,必须安装,它为jdk的运行提供必需的环境. public ...

  7. Spark 源码浅读-SparkSubmit

    Spark 源码浅读-任务提交SparkSubmit main方法 main方法主要用于初始化日志,然后接着调用doSubmit方法. override def main(args: Array[St ...

  8. jenkins 配置任务

    新建筑任务 ""imuke 建一个自由风格的 要执行python .py程序,我们需要把.py所在的目录设置进去 如果保存的是在svn,需要把他的地址放进去 如图: 设置自动构建时 ...

  9. 关于AES-CBC模式字节翻转攻击(python3)

    # coding:utf-8 from Crypto.Cipher import AES import base64 def encrypt(iv, plaintext): if len(plaint ...

  10. python菜鸟教程基础入门

    一. 可以使用'\'来连接多行.但是有括号的则不需要 a=b+\ c+\ d a1=['a', 'b'] 引号可以是单,双,三引号均可 二. 1. python有5个标准类型:数字,字符串,列表,元组 ...