前言:

本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大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. Codeforces Edu Round 58 A-E

    A. Minimum Integer 如果\(d < l\),则\(d\)满足条件 否则,输出\(d * (r / d + 1)\)即可. #include <cstdio> #in ...

  2. Acwing 403. 平面

    以一个这个环为基准,剩下的边可以放在圈外,也可以放在圈内,两种状态. 如果两条线段出现了环上意义的交叉即冲突,即不能同时放在圈外/内. 这是典型的 2-SAT 问题,因为关系传递是无向的,即逆命题与原 ...

  3. Android全面解析之Window机制

    前言 你好! 我是一只修仙的猿,欢迎阅读我的文章. Window,读者可能更多的认识是windows系统的窗口.在windows系统上,我们可以多个窗口同时运行,每个窗口代表着一个应用程序.但在安卓上 ...

  4. Java静态方法和非静态方法之间的关系

    非静态方法 public class Demo2 {    public static void main(String[] args) {        //实例化这个类 new       //对 ...

  5. Linux下keepalived配置

    1.背景 节点1:192.168.12.35 节点2:192.168.12.36 2.keepalived安装 使用yum仓库安装keepalived [root@node01 ~]# yum ins ...

  6. win10平衡模式、高性能模式和卓越模式三种电池模式的区别

    win10在1803版本后,有了很多隐藏的功能.电池模式中的"卓越模式"就是其中之一. 互相比较一下: 节能模式:顾名思义是最省电的,此模式下会禁用一些系统特效,且CPU运行频率是 ...

  7. 安卓 Android Studio 下载

    http://www.android-studio.org/    下载地址 https://blog.csdn.net/qq_41976613/article/details/91432304    ...

  8. Hive数据倾斜优化

    在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显.主要是因为在Job完成后的所得到的Counters是整个Job的总和,优化是基于这些Counters得出的平 ...

  9. Getting unknown property: common\models\Teacher::auth_Key

    找了一个半小时,不知道为什么会缺少这个属性,数据库里面的字段明明都是有的. 然后随后找到了原因,是因为key中的k大写了,所以无法识别这个属性.把自己坑到了,以此为戒,以后多注意细节问题

  10. win10新版wsl2使用指南

    本篇文章会介绍win10中wsl2的安装和使用以及遇到的常见问题比如如何固定wsl2地址等问题的总结. 一.wsl2简介 wsl是适用于 Linux 的 Windows 子系统,安装指南:适用于 Li ...