前言:

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

    color/visual see look color dark light beautiful shade black blue brown clear gray green orange red ...

  2. 算法——n皇后问题

    n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击. 给定一个整数 n,返回所有不同的 n 皇后问题的解决方案. 每一种解法包含一个明确的 n 皇后问题的棋 ...

  3. js实现转盘抽奖

    大转盘抽奖,主要通过css3的"transform:rotate(0deg)"属性来控制元素的旋转角度来实现. 通常,抽奖的过程需要渐进的效果,所以直接通过旋转属性写比较繁琐. 这 ...

  4. ORA-29701: unable to connect to Cluster Synchronization Service

    修改主机名后,has无法启动,将has启动之后,尝试ASMCA,出现如图提示: 再尝试登陆asm实例,出现日下提示: [oracle@edgzrip2-+ASM ~]$ sqlplus / as sy ...

  5. 2020-2021-1 20209307《Linux内核原理与分析》第三周作业

    一.计算机的三大法宝 存储程序计算机.函数调用堆栈机制.中断机制 二.堆栈 堆栈的作用:记录函数调用框架.传递函数参数.保存返回值的地址.提供局部变量存储空间 堆栈操作:push栈顶地址减少四个字节. ...

  6. CSS—— div+css

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  7. MySQL高可用(一)主备同步:MySQL是如何保证主备一致的

    主备同步,也叫主从复制,是MySQL提供的一种高可用的解决方案,保证主备数据一致性的解决方案. 在生产环境中,会有很多不可控因素,例如数据库服务挂了.为了保证应用的高可用,数据库也必须要是高可用的. ...

  8. 微服务之间如何共享DTO?

    1. 概述 近些年来,微服务变得越来越流行.微服务基本特征是模块化.独立.易于扩展的.它们之间需要协同工作并交换数据.为了实现这一点,我们创建了名为 DTO 的共享数据传输对象.在本文中,我们将介绍在 ...

  9. 用Python分析北京市蛋壳公寓租房数据

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 近期,蛋壳公寓"爆雷"事件持续发酵,期间因拖欠房东房租与租客退款,蛋壳公寓陷入讨 ...

  10. NET 5 Cron表达式

    cron表达式通过特定的规则指定时间,用于定时任务 1. 整体结构 cron表达式是一个字符串,分为6或7个域,每两个域之间用空格分隔,其语法格式为: "秒域 分域 时域 日域 月域 周域 ...