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

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

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

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

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

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

思路
关键词:确定起点终点单源最短路 无向图
Dijkstra算法就是生而为了解决这种题目的。不过这道题需要我们找出所有最短路的数量,那就必须在原来的标准代码上做点修改,不能找到终点就跳出Dijkstra函数,而是要完全遍历全图。
后面递归输出路径的时候则是利用了先前Dijkstra函数中生成使用的两组数据:从起点S到各结点的最短路径长度,从起点S到各结点的救援队数量;利用这个数据,我们从终点开始遍历他的所有边,若存在某条边DA连接终点D和某结点A使得“从起点S到A能获得的最大救援队数量+D点的救援队数量==从起点S到D能获得的最大救援队数量”&&“从起点S到A的最短路径长度+边DA的长度==从起点S到D的最短路径长度”那么这个结点A就必然是起点S到终点D最短路径最多救援队路径上最靠近终点D的那个驿站。

点击访问 PTA-测验

#include <stdio.h>
#include<stdlib.h>
#define FULL 250001
/*
提交时间    状态  分数  题目  编译器 耗时  用户
2018/1/23 11:57:04  答案正确    25  7-35    C (gcc) 238 ms  569985011
测试点 提示  结果  耗时  内存
0   sample  答案正确    2 ms    240KB
1   5条不同的最短路    答案正确    2 ms    244KB
2   最小N和M   答案正确    2 ms    156KB
3   最大N和M,随机数据构成完全图 答案正确    238 ms  2196KB
*/
typedef struct node *Node;
typedef struct {int Node;//目标结点int Lenth;//边长
} data;
struct node {data Reached[501];//与之有边连接的结点集合int right;//集合里的结点个数
};int teams[501];//保存每个结点带有的救援队数目
int Lenth[501][3];//[0]记录从起点出发到各结点的路径长度 ;[1]记录该路径能获取的救援队总数;【2】记录等长路径条数
Node Map;//地图int cmp(const void*a,const void*b) {//data*x=(data*)a;data*y=(data*)b;if(x->Lenth!=y->Lenth) {return x->Lenth-y->Lenth;} else if(teams[x->Node]!=teams[y->Node]) {return teams[y->Node]-teams[x->Node];} else  return teams[x->Node]-teams[y->Node];
}void Dijkstra(int);
void DFS(int,const int);
int main() {int N,M,S,D;//结点数、边数、起点、终点scanf("%d%d%d%d",&N,&M,&S,&D);Map=(Node)malloc(sizeof(struct node)*N);//初始化地图上的结点for(int i=0; i<N; Map[i++].right=0);for(int i=0; i<N; scanf("%d",&teams[i++]));//读入每个结点的价值——城市拥有的救援队数量{//读入地图信息,并排序整理while(M--) {int a,b,lenth;scanf("%d%d%d",&a,&b,&lenth);Map[a].Reached[Map[a].right].Node=b;Map[a].Reached[Map[a].right++].Lenth=lenth;Map[b].Reached[Map[b].right].Node=a;Map[b].Reached[Map[b].right++].Lenth =lenth;}for(int i=0; i<N; i++) {
//          printf("\n%d:",i);qsort(Map[i].Reached,Map[i].right,sizeof(data),cmp);for(int j=0; j<Map[i].right; j++) {
//              printf("{%d-%d}",Map[i].Reached[j].Node,Map[i].Reached[j].Lenth);}}}for(int i=0; i<N; Lenth[i++][0]=FULL); //[0]初始化设定从起点到所有其他结点的路径长度为无穷;Lenth[S][0]=0;Lenth[S][1]=teams[S];Dijkstra(S);printf("%d %d\n",Lenth[D][2],Lenth[D][1]);DFS(D,S);printf("%d",D);return 0;
}void Dijkstra(int a) {//戴克斯特拉算法for(int i=0; i<Map[a].right; i++) {data temp=Map[a].Reached[i];if(Lenth[a][0]+temp.Lenth<Lenth[temp.Node][0]) {Lenth[temp.Node][0]=Lenth[a][0]+temp.Lenth;Lenth[temp.Node][1]=Lenth[a][1]+teams[temp.Node];Lenth[temp.Node][2]=1;Dijkstra(temp.Node);} else if(Lenth[a][0]+temp.Lenth==Lenth[temp.Node][0]) {if(Lenth[a][1]+teams[temp.Node]>Lenth[temp.Node][1]) {Lenth[temp.Node][1]=Lenth[a][1]+teams[temp.Node];}++Lenth[temp.Node][2];Dijkstra(temp.Node);}}}void DFS(int dd,const int S) {//深度优先,从终点递归回溯, 如果存在某个结点:它到终点的边长加上它到起点的长度== 终点到原点的长度&&它到起点的救援队数量+终点的救援队数量== 起点到终点的救援队数量,那么这个结点一定是最短路上的一个结点。if(dd==S)return;for(int i=0; i<Map[dd].right; i++) {data temp=Map[dd].Reached[i];if(Lenth[temp.Node][0]+temp.Lenth==Lenth[dd][0]&&Lenth[temp.Node][1]+teams[dd]==Lenth[dd][1]) {
//          printf("*");DFS(temp.Node,S);printf("%d ",temp.Node);}}
}

5-35 城市间紧急救援 (25分)相关推荐

  1. 5-35 城市间紧急救援 (25分) pat 数据结构

    题目连接 https://pta.patest.cn/pta/test/15/exam/4/question/862 5-35 城市间紧急救援   (25分) 作为一个城市的应急救援队伍的负责人,你有 ...

  2. PTA7-12 城市间紧急救援 (25 分)(dijkstra+dp)(简单易懂的写法)

    PTA7-12 城市间紧急救援 (25 分) 关于这个题呢,我当时也想了很久没有一点头绪.所以,菜鸡的我一如既往的打开了CSDN(手动滑稽).我看了很多大佬的写法,最普遍的应该就是dijkstra+d ...

  3. 7-11 城市间紧急救援 (25 分)

    7-11 城市间紧急救援 (25 分) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速 ...

  4. L2-001 城市间紧急救援 (25分)(迪杰斯特拉算法)

    L2-001 城市间紧急救援 (25分)(迪杰斯特拉算法) 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一 ...

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

    //迪杰斯特拉算法求城市间紧急救援 #include<iostream> #include<cstring> using namespace std; #define num ...

  6. 城市间紧急救援 (25 分)【dijkstra模板 超时原因】

    立志用最少的代码做最高效的表达 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度 ...

  7. 7-35 城市间紧急救援 (25 分)(思路加详解)

    一:题目 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城 ...

  8. 7-2 城市间紧急救援 (25 分)

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...

  9. 7-68 城市间紧急救援 (25 分)

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...

最新文章

  1. Android APK的签名--笔记版 V1 签名和V2签名总结
  2. 跑monkey需要安装什么_安装隔音吊顶需要注意什么 隔音吊顶材料推荐
  3. 模拟器不全屏_puNES 适用于 Windows 和 Linux 的开源 NES 模拟器
  4. AVR 工具指南(一)
  5. PHP表单常用正则表达式(URL、HTTP、手机、邮箱等)
  6. arraycolumn php5.4以下怎么用,兼容php5.4和更低版本php的array_column公共方法
  7. Linux——Ubuntu使用个给力的镜像,安装软件速度飞快
  8. Windows 64位安装 memcached
  9. 【浪漫程序员系列】情人节给女友写代码表达爱意,让她感动到哭
  10. 电脑有独显内存还被占用_内存条:独立显卡显存,正式再见
  11. 上海亚商投顾:沪指震荡反弹 游戏、传媒概念股再度大涨
  12. Bootstrap 进度条媒体对象和 Well 组件
  13. handler相关学习(三)handler必背
  14. 使用 Chrome DevTools 模拟缓慢的 3G 网络速度
  15. jquery动态添加带有样式的HTML标签元素
  16. 3、组推荐系统及其应用研究---张玉洁(2016)
  17. Java多线程2.3.生产者与消费者之间的关系2
  18. SwapIdc高仿小鸟云模板/手机和解决方案页面
  19. Unity中的布料系统
  20. OpenGL 环境配置教程-库文件汇总【glfw/glew/glad/glm/std_img】

热门文章

  1. 全栈开发实战(一)——简易博客社区后端搭建教程(附源码)
  2. Oracle 字符串比较大小
  3. 批量计算机添加网络打印机方法,通过IP添加网络打印机打印方法图解
  4. xxl-job(v2.1.0 Release)执行器端的执行器自动注册原理
  5. dom4j解析数组类型XML
  6. 二叉树的创建和遍历实现
  7. 接口测试中模拟post四种请求数据
  8. 渗透测试中的certutil
  9. 如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀)
  10. OpenJudge2.6基本算法之动态规划9267:核电站