解题步骤:

1.初始化:设置mat[][]存放点之间的距离,vis[]存放点的选取情况,people[]存放初始时每个城市的人数,man[]存放到达每个城市的救援队的最多的人数,num[]存放到达每个城市的最多的人数(在最短路径的基础之上),dist[]存放从起点开始到达每个城市的最短的路径(随着每次选取点而更新)

2.核心算法:按照Dijkstra算法思想,从起点出发,不断选择一个点使得通过该点到达其他点的距离比直接通过已知点到达的距离更短,则更新最短距离数组dist[],这里分为两种情况1:确实是通过某个点能使得到达其他点的距离更短,则除了修改最短距离数组dist之外,此时通过该点为跳板达到点的行走方案数量就是到达该跳板点的行走方案数量,而到达该点的人数就是到达跳板点的人数加上该点本来就有的人数。(因为人数是必须以最短距离为基础的,只要有更短的距离,则人数就要修改成那种方案下的人数)2:如果通过选中的点到达其他点的距离和原本已知点达到该点的距离是相等的,则需要增加到达该点的行走方案的总数,以及可能要修改同样是到达该点的时最多可召集的救援队的数量。方案增加的方法是原来到x点的走法数量加上到达跳板点的走法的数量,而人数的修改则是选取原来方案到x的人数和到达跳板点最多人数+x点的人数二者之间的最大值

3.注意点:对于初始化的时候,我们要注意的是除了设置所有从起点开始不可达的点的距离为无穷大(0x3f3f3f3f)之外, 我们巧妙的设置初始点到自己的距离为0,通过这样的方式,第一个选中的跳板是出发点自身,则会为man[],num[]数组进行一遍赋值,这样后续的核心算法的判断和修改过程才能成立

 #include<iostream>
#include<string.h>
using namespace std; const int Max = 0x3f3f3f3f;
const int N = ;
int mat[N][N];
int dist[N]; //记录随着每次获取一个新的点之后从起点开始到每个点的最短距离的最新情况
int people[N]; //记录每个城市初始的救援队的人数
int num[N]; //记录从起点开始到达某个点的最短路径的条数
int man[N]; //记录从起点开始在最短路径的基础上到达某个城市的最多的人数
int vis[N]; //记录某个城市是否被走过 1走过 0未走过
int n, m, s, t; void init(){
for(int i = ; i < n; i++) scanf("%d", &people[i]);
memset(mat, Max, sizeof(mat));
memset(vis, , sizeof(vis));
memset(man, , sizeof(man));
memset(num, , sizeof(num));
for(int i = ; i <= m; i++){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
mat[x][y] = z;
mat[y][x] = z;
}
mat[s][s] = ; //设置到达自己本身为0 则第一次必定会选择自己
for(int i = ; i < n; i++){
dist[i] = mat[s][i];
}
num[s] = ; //设置初始到达起点的走法有1条
man[s] = people[s]; //设置到达起点的可以召集的人数为起点的人数
} int search(){
int k = -;
int mmin = Max;
for(int i = ; i < n; i++){
if(vis[i] == && dist[i] < mmin){ //这个点没走过则选取一个最小的距离,确保每次选择的点是到达该点的最短的路径
k = i;
mmin = dist[i];
}
}
//因为至少存在一条通路所以k的返回值不可能是-1 (若图是不连通的则某个时刻k会返回-1)
return k;
} void run(){
for(int i = ; i <= n; i++){ //有n个点 则需要查询n-1次能走完所有的点
int k = search(); //查询最短距离的点
vis[k] = ; //标记走过该点
for(int j = ; j <= n-; j++){
if(vis[j] == && dist[j] > mat[k][j] + dist[k]){
dist[j] = mat[k][j] + dist[k];
num[j] = num[k]; //如果通过k到达j的路径是最短的 则到达j的条数就是达到k的条数
man[j] = people[j] + man[k];
}
//这里必须要用else if因为执行完上面的语句之后 dist[j] == mat[k][j] + dist[k]必定会成立则会导致再次执行下面的语句
else if(vis[j] == && dist[j] == mat[k][j] + dist[k]){
num[j] += num[k];
man[j] = max(man[j], people[j] + man[k]);
}
}
}
printf("%d %d\n", num[t], man[t]);
} int main(){
while(scanf("%d%d%d%d", &n, &m, &s, &t) != EOF){
init();
run();
}
return ;
}

PAT甲级1003题解——Dijkstra的更多相关文章

  1. 图论 - PAT甲级 1003 Emergency C++

    PAT甲级 1003 Emergency C++ As an emergency rescue team leader of a city, you are given a special map o ...

  2. PAT甲级1003. Emergency

    PAT甲级1003. Emergency 题意: 作为一个城市的紧急救援队长,你将得到一个你所在国家的特别地图.该地图显示了几条分散的城市,连接着一些道路.每个城市的救援队数量和任何一对城市之间的每条 ...

  3. PAT甲级1017题解——模拟排序

    题目分析: 本题我第一次尝试去做的时候用的是优先队列,但是效率不仅代码量很大,而且还有测试样例过不去,很显然没有找到一个好的数据结构来解决这道题目(随着逐渐的刷PAT甲级的题会发现有时选择一个好的解题 ...

  4. 2019秋季PAT甲级_C++题解

    2019 秋季 PAT (Advanced Level) C++题解 考试拿到了满分但受考场状态和知识水平所限可能方法不够简洁,此处保留记录,仍需多加学习.备考总结(笔记目录)在这里 7-1 Fore ...

  5. PAT 甲级1003 Emergency (25)(25 分)(Dikjstra,也可以自己到自己!)

    As an emergency rescue team leader of a city, you are given a special map of your country. The map s ...

  6. 1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs

    前言: 本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大orz,这里给出柳神的题解地址:https://blog.csdn.net/liuchuo/article/detail ...

  7. PAT 甲级 1003 Emergency

    https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376 As an emergency rescue ...

  8. PAT 甲级 1003. Emergency (25)

    1003. Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emerg ...

  9. PAT甲级1015题解——令人迷茫的翻译

    题目分析: 本题计算过程简单,但翻译令我迷茫:题意读清楚很重要(反正我是懵逼了)对于一个10进制的数,如果它是一个素数,把它转换成d进制,再将这个序列逆序排,这个逆序的d进制数的10进制表示如果也是素 ...

随机推荐

  1. EasyNVR摄像机网页无插件直播方案H5前端构建之:如何播放HLS(m3u8)直播流

    背景描述 HLS (HTTP Live Streaming)是Apple的动态码率自适应技术,主要用于PC和Apple终端的音视频服务,包括一个m3u(8)的索引文件,TS媒体分片文件和key加密串文 ...

  2. swoole实验版聊天室

    “swoole实验版聊天室”是依据一堂swoole培训课内容改编的,结合了bootstrap前端框架.redis数据库.jquery框架等实现基本功能,只是体现了swoole的应用,并不是为了专门写个 ...

  3. Apache限制IP并发数和流量控制

    使用mod_limitipconn模块限制IP并发连接数安装: wget http://dominia.org/djao/limit/mod_limitipconn-0.24.tar.bz2 tar ...

  4. Swift编码总结10

    1.打开App显示文件已损坏,打不开,您应该将它移到废纸篓,怎么办? 终端输入执行:sudo spctl --master-disable 2.Mac的Siri打开网页控制台,进入开发中模式:不过我觉 ...

  5. MySQL报错Packet for query is too large问题解决

    今天用java写了批量插入运行时,报错: Error updating database.  Cause: com.mysql.cj.jdbc.exceptions.PacketTooBigExcep ...

  6. jQuery.js引入时要在其他js文件之前,否则js中无法识别jQuery的语法

  7. static binding/dynamic binding

    static binding/dynamic binding class Person { private void who() { System.out.println("Inside p ...

  8. 【转帖】lsof命令总结

    lsof命令总结 https://www.cnblogs.com/chenqionghe/p/10677179.html 一.lsof是什么 lsof (list open files)是一个列出当前 ...

  9. Java多线程编程(3)--线程安全性

    一.线程安全性   一般而言,如果一个类在单线程环境下能够运作正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能运作正常,那么我们就称其是线程安全的.反之,如果一个类在单线程环境下运作 ...

  10. 关于 exynos 4412 按键中断 异步通知

    以下是驱动测试代码: //内核的驱动代码 #include <linux/init.h> #include <linux/module.h> //for module_init ...