前言:

本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大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. 学习笔记:Kruscal 重构树

    网上感觉没有什么很详细 + 证明的讲解啊) 前置:Kruskal 求最小生成树. 这个算法可以将一棵树 / 无向连通图重构成一颗有性质的新树. 算法可以解决一些树上瓶颈边权之类的问题,可以把需要持久化 ...

  2. Luogu-P3205-HNOI2010-合唱队

    题目地址 思路 这道题其实是P3146 [USACO16OPEN]248的升级版,但是N的范围很大,为262144.原先的O(N3)的方法自然会TLE,甚至O(N2)的方法也不足以解决. 定义f[i] ...

  3. SpringBoot+Redis相关配置文件

    springboot整合redis配置类 package com.yalong.config; import com.fasterxml.jackson.annotation.JsonAutoDete ...

  4. oracle 11g调优常用语句

    1.查询表的基数及选择性 select a.column_name,       b.num_rows,       a.num_distinct cardinality,       round( ...

  5. 关于golang的time包总结

    目录 前言 time包详解 总结 前言 各种编程语言都少不了与时间有关的操作,因为很多判断都是基于时间,因此正确和方便的使用时间库就很重要额. golang提供了import "time&q ...

  6. 移动端 CSS3动画属性

    一.transform 转换属性 #1. translate位移 transform : translate(50px,100px); //把元素水平移动 50 像素,垂直移动 100 像素 tran ...

  7. python 协程并发下载图片

    1 import aiohttp 2 import asyncio 3 import time 4 5 async def dl_coroutine(session,url): 6 print('开始 ...

  8. 真香!Python十大常用文件操作,轻松办公

    日常对于批量处理文件的需求非常多,用Python写脚本可以非常方便地实现,但在这过程中难免会和文件打交道,第一次做会有很多文件的操作无从下手,只能找度娘. 本篇文章整理了10个Python中最常用到的 ...

  9. Mysql 中的MDL

    本文可以结合 MySQL中的事务原理和锁机制 查看. 首先简单了解一下 mysql 的 sql 类型: 1.数据定义语言 DDL:Create.Drop.Alter 操作.用于定义库和表结构的. 2. ...

  10. C# HTTP1.0 1.1 2.0与HTTPS 、TCP/IP协议的UDP与TCP、 Socket介绍与WebSocket

    一.HTTP1.0 1.1 2.0和HTTPS 1.HTTP协议是什么? HTTP协议是超文本传输协议的缩写,英文是Hyper Text Transfer Protocol.它是从WEB服务器传输超文 ...