PAT甲级1003题解——Dijkstra
解题步骤:
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的更多相关文章
- 图论 - PAT甲级 1003 Emergency C++
PAT甲级 1003 Emergency C++ As an emergency rescue team leader of a city, you are given a special map o ...
- PAT甲级1003. Emergency
PAT甲级1003. Emergency 题意: 作为一个城市的紧急救援队长,你将得到一个你所在国家的特别地图.该地图显示了几条分散的城市,连接着一些道路.每个城市的救援队数量和任何一对城市之间的每条 ...
- PAT甲级1017题解——模拟排序
题目分析: 本题我第一次尝试去做的时候用的是优先队列,但是效率不仅代码量很大,而且还有测试样例过不去,很显然没有找到一个好的数据结构来解决这道题目(随着逐渐的刷PAT甲级的题会发现有时选择一个好的解题 ...
- 2019秋季PAT甲级_C++题解
2019 秋季 PAT (Advanced Level) C++题解 考试拿到了满分但受考场状态和知识水平所限可能方法不够简洁,此处保留记录,仍需多加学习.备考总结(笔记目录)在这里 7-1 Fore ...
- 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 ...
- 1018 Public Bike Management (30分) PAT甲级真题 dijkstra + dfs
前言: 本题是我在浏览了柳神的代码后,记下的一次半转载式笔记,不经感叹柳神的强大orz,这里给出柳神的题解地址:https://blog.csdn.net/liuchuo/article/detail ...
- PAT 甲级 1003 Emergency
https://pintia.cn/problem-sets/994805342720868352/problems/994805523835109376 As an emergency rescue ...
- PAT 甲级 1003. Emergency (25)
1003. Emergency (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue As an emerg ...
- PAT甲级1015题解——令人迷茫的翻译
题目分析: 本题计算过程简单,但翻译令我迷茫:题意读清楚很重要(反正我是懵逼了)对于一个10进制的数,如果它是一个素数,把它转换成d进制,再将这个序列逆序排,这个逆序的d进制数的10进制表示如果也是素 ...
随机推荐
- java核心技术(卷一)
一,java基本程序设计结构: 1,在网页中运行的 Java 程序称为 applet. 要使用 applet ,需要启用 Java 的 Web 浏览器执行字节码. 2,jdk安装目录下的 src.zi ...
- eclipse不提示
1.菜单window->Preferences->Java->Editor->Content Assist->Enable auto activation 选项要打上勾 ...
- Java数组操作类
最近又重新在看慕课网的数据结构,然后把示例代码整理一下. public class Array<E> { private E[] data; private int count = 0; ...
- Spark学习(2) RDD编程
什么是RDD RDD(Resilient Distributed Dataset)叫做分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.弹性.里面的元素可并行计算的集合 RDD允 ...
- 如何同时读取 TDateTimePicker 的 Date 和 Time ?
由于 TDateTimePicker 只能用于日期或时间,不能同时使用.如果将Kind属性设置为dtkDate,则可以指定自定义DATE格式,但忽略任何TIME格式,并且Time未定义使用该属性.如果 ...
- Mysql表字段命令alter add
alter add命令用来增加表的字段. alter add命令格式:alter table 表名 add字段 类型 其他; 例如,在表MyClass中添加了一个字段passtest,类型为int(4 ...
- vs2017(Visual Studio Code)安装汉化
一.打开vs2017,菜单栏选择 工具—扩展更新 二.联机搜索Chinese,选择简繁转换插件,点击下载,关闭vs,安装插件,重启即可汉化生效.
- 浮动IP地址(Float IP)与 ARP欺骗技术
浮动IP地址: 一个网卡是可以添加多个IP的. 就是多个主机工作在 同一个集群中,即两台主机以上.每台机器除了自己的实IP外,会设置一个浮动IP,浮动IP与主机的服务(HTTP服务/邮箱服务)绑在一起 ...
- python 代码中log表示含义
log表示以e为底数的对数函数符号.其验证代码如下: a=np.log(np.e )print(a)print(np.e)
- 换个语言学一下 Golang (8)——指针
定义 所谓指针其实你可以把它想像成一个箭头,这个箭头指向(存储)一个变量的地址. 因为这个箭头本身也需要变量来存储,所以也叫做指针变量. Go的指针不支持那些乱七八糟的指针移位.它就表示一个变量的地址 ...