解题步骤:

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. Mac下进入MySQL命令行

    /usr/local/MySQL/bin/mysql -u root -p 其中,root为数据库用户名

  2. android问题总结:

    1. android:focusableInTouchMode="true" 属性: 控制 子view不获取焦点:   <android.support.v4.widget. ...

  3. 远程控制分析之VBS编码转换

    简介 分析这种VBS简单chr()函数编码的脚本技巧.只需要把vbs的execute()函数换成信息输出到控制台(dos窗口)函数就可以了. WSH.Echo "print your mes ...

  4. C++中的结构体所占内存空间总结

    因为结构体有时候需要字节对齐.一般而言,struct 的 sizeof 是所有成员字节对齐后长度相加,而 union 的 sizeof 是取最大的成员长度. 在默认情况下,编译器为每一个变量或数据单元 ...

  5. [数据结构 - 第3章] 线性表之单链表(C++实现)

    一.类定义 单链表类的定义如下: #ifndef SIGNALLIST_H #define SIGNALLIST_H typedef int ElemType; /* "ElemType类型 ...

  6. (CSDN 迁移) JAVA循环删除List的某个元素

    若列表中只可能存在一个则可以用简单的循环删除,不多说. 若列表中可能存在多个,尤其是可能有多个连续的需要删除,用简单循环有可能发生异常. 需要使用迭代器(Iterator),两种具体实现: 逻辑上是一 ...

  7. SQL Server 索引的最佳实践

    索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其 ...

  8. Spark学习(4) Spark Streaming

    什么是Spark Streaming Spark Streaming类似于Apache Storm,用于流式数据的处理 Spark Streaming有高吞吐量和容错能力强等特点.Spark Stre ...

  9. Java面试题及答案汇总(一)

    Java 基础 1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,java 开发工具包,提供了 java 的开发环境和运行环境. JRE:Java Ru ...

  10. 对于Node中Express框架的中间件概念的感知

    中间件是什么呢? 中间件就是客户端http请求发起传送到服务器和服务器返回响应之间的一些处理函数. 为什么要使用中间件? 通过中间件,可以对数据进行操作使得我们能方便地操作请求数据编写服务器响应.如b ...