PTA-数据结构 Dijkstra 城市间紧急救援

城市间紧急救援(25 分)

作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。

输入格式:

输入第一行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N?1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。

第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。

输出格式:

第一行输出最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出结尾不能有多余空格。

输入样例:

4 5 0 3
20 30 40 10
0 1 1
1 3 2
0 3 3
0 2 2
2 3 2

输出样例:

2 60
0 1 3

代码及分析如下:
  1 /*
  2
  3 目标:
  4 求最短路径长度和条数以及最短路径下的最多救援队数。(优先选择距离最短的路径,距离相同考虑救援队数量)
  5 代码解释:
  6 Way数组:Way【i】从出发点到i点的最短路径的数量
  7 Sum数组:Sum【i】从出发点到i点的一条或多条最短路径下的救援队数量最多的路径的救援队数量
  8 Peo数组:Peo【i】代表下表为i的点的初始救援队个数
  9 Move数组:Move【i】若为true代表小标为i的点已经被访问过了,为false则没有;
 10 Dist数组:Dist【i】代表从出发点到i点的最短距离
 11 思路:
 12 基本的最短路问题(这里选择迪杰斯特拉,注意它不能解决负权边问题)
 13 除此之外为了解决最短路径条数和最短路下的最大救援队数量引入Way数组和Sum数组
 14     递推公式
 15     Way【i】=ΣWay【j】(j为使得Dist【i】最小的i点的前驱,可能有多个),显然边界条件Way【s】=1(s为出发点);
 16     Sum【i】= Sum【j】+Peo【i】(j为最短路上i的前驱)
 17 */
 18 #include <iostream>
 19 #include <stdio.h>
 20 #include <stdlib.h>
 21 using namespace std;
 22 #define Max 500
 23 #define Sky 99999  //表示两点之间没有路径时的距离
 24 int distances[Max][Max],Top,Start,End,Edge;  //分别为 两城市间距离的二维数组 城市个数 起点 终点 边数
 25 int Dist[Max],Move[Max],Peo[Max],Sum[Max],Way[Max];
 26 void Dis()
 27 {
 28 int i,j;
 29 //初始化边界条件
 30     for(i=0;i<Top;i++)
 31     {
 32         Dist[i]=distances[Start][i];  //把最短距离初始化为起点到该点的直接距离
 33         Move[i]=false;  //每个点初始化为都没有访问
 34     }
 35     Dist[Start]=0;  //起点到本身距离为零
 36     Move[Start]=true;  //起点已经被访问
 37     Sum[Start]=Peo[Start];  //团队数仅为起点团队数
 38     Way[Start]=1;  //路径条数为1
 39
 40     for(i=1;i<=Top-1;i++)  //除了起点还要循环top-1 次才能完成所有定点的访问
 41     {
 42         int minw=Sky;  //保存距离出发点最近的点距离出发点的距离,初始化为最大
 43         int k; //保存该点的编号
 44         for(j=0;j<Top;j++)//遍历每一个顶点
 45         {
 46             if(!Move[j])  //j没有被访问的话
 47             {
 48                 if(minw>Dist[j])//如果找到距离出发点更近的点,更新minw和k
 49                 {
 50                     minw=Dist[j];
 51                     k=j;
 52                 }
 53             }
 54         }
 55
 56         Move[k]=true;  //更新过的k顶点处理完毕 标记数组为true
 57
 58         for(j=0;j<Top;j++)//遍历每一个顶点
 59         {
 60             if(!Move[j])//如果没有访问(处理完毕)
 61             {
 62                 if(Dist[j]==Dist[k]+distances[k][j])/*如果从起点到下标j点的距离等于从起点先到k再到j的距离*/
 63                 {
 64                     Way[j]+=Way[k];//加和
 65                     if(Sum[j]<Sum[k]+Peo[j])//路径距离相同时,团队数更多
 66                     {
 67                         Sum[j]=Sum[k]+Peo[j];//团队数更新
 68                     }
 69                 }
 70                 if(Dist[j]>Dist[k]+distances[k][j])/* 如果从起点到下标j点的距离等于从起点先到k再到j的距离*/
 71                 {
 72                     Dist[j]=Dist[k]+distances[k][j];
 73                     Sum[j]=Sum[k]+Peo[j];
 74                     Way[j]=Way[k];
 75                 }
 76
 77             }
 78         }
 79     }
 80 }
 81 void Dfs(int end,int Sump)
 82 {
 83     if(end==Start)//边界条件
 84     {
 85         return;
 86     }
 87     for(int j=0;j<Top;j++)//遍历每一个顶点
 88     {
 89         if(Sump-Peo[end]==Sum[j] && Dist[end]-distances[end][j]==Dist[j])/*寻找当前点的前驱点*/
 90         {
 91            Dfs(j,Sum[j]);
 92            cout<<j<<"";
 93         }
 94     }
 95
 96 }
 97 int main( )
 98 {
 99      cin>>Top>>Edge>>Start>>End;
100      int i,j;
101      for(i=0;i<Top;i++)
102      for(j=0;j<Top;j++)
103      distances[i][j]=Sky;
104
105      for(i=0;i<Top;i++)
106      {
107          scanf("%d",&Peo[i]);
108      }
109
110      for(i=0;i<Edge;i++)
111      {
112          int x,y,z;
113          scanf("%d%d%d",&x,&y,&z);
114          distances[x][y]=distances[y][x]=z;//存入直接相连城市间的距离z
115      }
116      Dis();
117      cout<<Way[End]<<""<<Sum[End]<<endl;
118
119      Dfs(End,Sum[End]);
120      cout<<End<<endl;
121
122
123     return 0;
124 }
坚持不懈地努力才能成为大神!
时间: 2024-07-30 17:33:32

PTA-数据结构 Dijkstra 城市间紧急救援的相关文章

PTA数据结构与算法题目集(中文) 7-35 城市间紧急救援 (25 分)

PTA数据结构与算法题目集(中文)  7-35 城市间紧急救援 (25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队. 输入格式: 输入第一行给出4个正整数N.M.S.D,其中N(2)是城市的个数,顺便假设城市的编号为0 ~ (:M是快速道路的条数

5-35 城市间紧急救援 (25分)

5-35 城市间紧急救援   (25分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队. 输入格式: 输入第一行给出4个正整数NN.MM.SS.DD,其中NN(2\le N\le 5002≤N≤500)是城市的个数,顺便假设城市的编号为0 ~ (N-1)

PTA数据结构与算法题目集(中文) 7-16

PTA数据结构与算法题目集(中文)  7-16 7-16 一元多项式求导 (20 分) 设计函数求一元多项式的导数. 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: 以与输入相同的格式输出导数多项式非零项的系数和指数.数字间以空格分隔,但结尾不能有多余空格. 输入样例: 3 4 -5 2 6 1 -2 0 输出样例: 12 3 -10 1 6 0题目分析:要注意判断输入停止的标志 利用~scanf来判断 其它问题到没发现 (

PTA数据结构与算法题目集(中文) 7-32

PTA数据结构与算法题目集(中文)  7-32 7-32 哥尼斯堡的“七桥问题” (25 分) 哥尼斯堡是位于普累格河上的一座城市,它包含两个岛屿及连接它们的七座桥,如下图所示. 可否走过这样的七座桥,而且每桥只走过一次?瑞士数学家欧拉(Leonhard Euler,1707—1783)最终解决了这个问题,并由此创立了拓扑学. 这个问题如今可以描述为判断欧拉回路是否存在的问题.欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个无向图,问是否存在欧拉回路? 输

PTA数据结构与算法题目集(中文) 7-43字符串关键字的散列映射 (25 分)

PTA数据结构与算法题目集(中文)  7-43字符串关键字的散列映射 (25 分) 7-43 字符串关键字的散列映射 (25 分) 给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数(将关键字Key中的最后3个字符映射为整数,每个字符占5位:再用除留余数法将整数映射到长度为P的散列表中.例如将字符串AZDEG插入长度为1009的散列表中,我们首先将26个大写英文字母顺序映射到整数0~25:再通过移位将其映射为3:然后根据表长得到,即是该字符串的散列映射位置. 发生冲突时请

PTA数据结构与算法题目集(中文) 7-14

PTA数据结构与算法题目集(中文)  7-14 7-14 电话聊天狂人 (25 分) 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤),为通话记录条数.随后N行,每行给出一条通话记录.简单起见,这里只列出拨出方和接收方的11位数字构成的手机号码,其中以空格分隔. 输出格式: 在一行中给出聊天狂人的手机号码及其通话次数,其间以空格分隔.如果这样的人不唯一,则输出狂人中最小的号码及其通话次数,并且附加给出并列狂人的人数. 输入样例: 4 130057

PTA数据结构与算法题目集(中文) 7-27

PTA数据结构与算法题目集(中文)  7-27 7-27 家谱处理 (30 分) 人类学研究对于家族很感兴趣,于是研究人员搜集了一些家族的家谱进行研究.实验中,使用计算机处理家谱.为了实现这个目的,研究人员将家谱转换为文本文件.下面为家谱文本文件的实例: John Robert Frank Andrew Nancy David 家谱文本文件中,每一行包含一个人的名字.第一行中的名字是这个家族最早的祖先.家谱仅包含最早祖先的后代,而他们的丈夫或妻子不出现在家谱中.每个人的子女比父母多缩进2个空格.

PTA数据结构与算法题目集(中文) 7-36 社交网络图中结点的“重要性”计算 (30 分)

PTA数据结构与算法题目集(中文)  7-36 社交网络图中结点的“重要性”计算 (30 分) 7-36 社交网络图中结点的“重要性”计算 (30 分) 在社交网络中,个人或单位(结点)之间通过某些关系(边)联系起来.他们受到这些关系的影响,这种影响可以理解为网络中相互连接的结点之间蔓延的一种相互作用,可以增强也可以减弱.而结点根据其所处的位置不同,其在网络中体现的重要性也不尽相同. “紧密度中心性”是用来衡量一个结点到达其它结点的“快慢”的指标,即一个有较高中心性的结点比有较低中心性的结点能够

PTA 数据结构 一元多项式求导 (仅供参考)

请勿粘贴 输入格式: 以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数).数字间以空格分隔. 输出格式: 以与输入相同的格式输出导数多项式非零项的系数和指数.数字间以空格分隔,但结尾不能有多余空格. 输入样例: 3 4 -5 2 6 1 -2 0 输出样例: 12 3 -10 1 6 0 #include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm>