L2-001 紧急救援(dijkstra算法)
题目:
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。
输入格式:
输入第一行给出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
dijkstra算法:
dijkstra算法是贪心算法在求解路径问题上的应用。
作用:dijkstra算法能够解决边权非负的加权有向图的单起点最短路径问题。也就是说,规定一个起点,就能够得到这个加权有向图中其他点距该起点的最短距离。
数据结构:数组known[ ]用于标记这些点的状态(已知、未知); 数组dis[ ],也就是下表中的dv,表示每个点到起点的距离,附初值时,除了起点自身,其他的点到起点的距离都设为无穷,在实际编程时,可用定义一个很大的数(比如99999999)作为常量为其赋值;数组pre[ ],也就是下表中的pv,表示引起dv变化的最后一个顶点,也就是以这种路径到达这个点经过的前一个点。
算法:以下面这个加权有向图为例,并假设开始结点为v1。初始配置如图9-12所示。每次更新下图的表格,算法都会选择未知的点中dv最小的一个标记为已知,然后去寻找这个点的下几个邻接点,如果该邻接点到这个已知点的距离加上这个已知点的dv小于该邻接点的dv,那么更新dv和pv,这其实就是从这个已知点这里走会更近的意思;如果该邻接点是已知的就跳过(因为每一次都是先将dv最小的点标记为已知,所以该点的dv不会更小)。

过程如图:


下表是每次更新的表格。在下面我直接把书上的讲解搬上来,书是《数据结构与算法分析:C语言描述》。








思路:
了解了dijkstra 以后,再来看这道题,发现题目就是在这个算法的基础上加了一个“救援队”和经过的结点数。那么我们在表格后多加两列就ok了,也就是在程序中加两个数组。最后按顺序输出路径那里使用了递归,具体见代码。
知识点for me:
1、fill()可以按照单元赋值,将一个区间的元素都赋同一个值,它在头文件<algorithm>里面。
它可以赋值任何,比如int数组:fill(arr, arr + n, 要填入的内容); 比如vector:fill(v.begin(), v.end(), 要填入的内容); 比如二维数组fill(f[0], f[0]+N*N, 要填入的内容);
上代码:
第一次写dijkstra,一些数组的命名感觉不是那么合适,将就看吧。
#include <iostream>
#include <algorithm>
using namespace std;
const int inf=;
int v,e,a,b;//点、边、起点、终点
int pv[];//路径中每个点的前一个点 void printPath(int v)//递归输出路线
{
if(v == a) {
printf("%d", v);
return ;
}
printPath(pv[v]);
printf(" %d", v);
}
int main() {
cin>>v>>e>>a>>b;
int help[v];//存储每个村的救援队
int x=;
for(int i=;i<v;i++)
{
cin>>x;
help[i]=x;
}
int f,t,l;
int dis[v][v];//边权
fill(dis[],dis[]+v*v,inf);
for(int i=;i<e;i++)
{
cin>>f>>t>>l;
dis[f][t]=l;
dis[t][f]=l;//注意!!道路是双向的!
}
int known[v]={};//最初所有的点都为未知
int dv[v];
fill(dv,dv+v,inf);//所有点到起点的距离除了起点自身是0,其余都是无穷
dv[a]=; int min;
int minn;
int num[v];//累加的救援队的数量
//num[a]=help[a];
fill(num,num+v,help[a]);
int way[v]={};//从出发点到v结点拥有的最短路径的条数
for(int i=;i<v;i++)//dijkstra
{
min=inf;
minn=-;
//找出未知且dv最小的一个点,将它设为已知
for(int j=;j<v;j++)
{
if(dv[j]<min&&known[j]==){
min=dv[j];
minn=j;
}
}
if(minn==-)//如果剩下未知的点全是dv=inf,break
break;
known[minn]=;
for(int k=;k<v;k++)//找该点邻接的下一个顶点,并求其dv
{
if(dis[minn][k]!=inf&&known[k]==){
if(dis[minn][k]+min<dv[k])
{
dv[k]=dis[minn][k]+min;
pv[k]=minn;
num[k]=num[minn]+help[k];
way[k]=way[minn];
}
else if(dis[minn][k]+min==dv[k]){
way[k]+=way[minn];//无论如何,到达k点的最短路径数量增加:原来的way[k]加上前一个结点的way
if(num[minn]+help[k]>num[k])//比较救援队的数量
{
pv[k]=minn;
num[k]=num[minn]+help[k];
}
}
}
} }
cout<<way[b]<<" "<<num[b]<<endl;
printPath(b);
return ;
}
杀不死我的使我更强大 _(:з」∠)_
L2-001 紧急救援(dijkstra算法)的更多相关文章
- L2-001. 紧急救援 (Dijkstra算法打印路径)
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...
- Dijkstra算法C#实现及其布线运用
大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 以下是空调布线对Dijkstra算法的运用,采用C#实现. 问题:室内机多台,室外机一台.寻找室内 ...
- 单源最短路径算法——Dijkstra算法(迪杰斯特拉算法)
一 综述 Dijkstra算法(迪杰斯特拉算法)主要是用于求解有向图中单源最短路径问题.其本质是基于贪心策略的(具体见下文).其基本原理如下: (1)初始化:集合vertex_set初始为{sourc ...
- 单源最短路——dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 问 ...
- Codeforces 843D (Dijkstra算法的优化,动态最短路)
题面 (http://codeforces.com/problemset/problem/843/D) 题目大意: 给定一张带权无向图,有q次操作 操作有两种 1 v 询问1到v的最短路 2 c 将边 ...
- PAT Advanced 1003 Emergency (25) [Dijkstra算法]
题目 As an emergency rescue team leader of a city, you are given a special map of your country. The ma ...
- 求两点之间最短路径-Dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...
- Dijkstra算法优先队列实现与Bellman_Ford队列实现的理解
/* Dijkstra算法用优先队列来实现,实现了每一条边最多遍历一次. 要知道,我们从队列头部找到的都是到 已经"建好树"的最短距离以及该节点编号, 并由该节点去更新 树根 到其 ...
- 关于dijkstra算法的一点理解
最近在准备ccf,各种补算法,图的算法基本差不多看了一遍.今天看的是Dijkstra算法,这个算法有点难理解,如果不深入想的话想要搞明白还是不容易的.弄了一个晚自习,先看书大致明白了原理,就根据书上的 ...
随机推荐
- UX2内核浏览加速技术纲要[带你解决WebView卡顿]
UX2内核是本人负责主要开发的浏览服务项目,其主要目的是为开发者提供一个简单好用.轻便的网络浏览服务.UX2内核的安卓端是基于WebView进行深度优化的,同时欢迎大家使用这个内核用于app页面或浏览 ...
- 大规模WEB服务技术
CPU负载的扩展很简单,增加相同结构的服务器,通过负载均衡来分散. I/O负载的扩展很困难.要考虑局部性.
- IsWindow,findwindow
原文:http://www.cnblogs.com/ahuo/archive/2007/12/05/983354.html IsWindow 函数功能:该函数确定给定的窗口句柄是否识别一个已存在的窗口 ...
- webstorm出现黑色块光标
取消掉此项对勾即可
- web images
ps切图时,我们保存时会要求选择文件格式. 一般来说,如果图像的色彩丰富,没有透明度的要求,则选择为jpeg格式: 如果图像色彩不丰富,我们就选择为png-8的格式,注意:ps中要选择无杂边,无仿色 ...
- redis3.2.8安装与简介
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. Redis 与其他 key - value 缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的 ...
- 【NLP_Stanford课堂】语言模型2
一.如何评价语言模型的好坏 标准:比起语法不通的.不太可能出现的句子,是否为“真实”或"比较可能出现的”句子分配更高的概率 过程:先在训练数据集上训练模型的参数,然后在测试数据集上测试模型的 ...
- .Net中初探Redis
一.简介 Redis是著名的NOSQL数据库,本质就是存储键值对结构的数据,为存储键值对数据做了优化,在大型网站中应用很多.Redis提供了数据的自动过期处理,因此适合存储临时数据. 和Redis类似 ...
- LINQ学习笔记(一)基本语法
1.LINQ简介 LINQ是Language Integrated Query的简称,它是集成在.NET编程语言中的一种特性.包括五个部分:LINQ to Objects.LINQ to DataSe ...
- MyEclipse中关于JRE System Library、Web App Libraries的疑惑
简要说明一下:其实,这三个都是jar包的存放集合. 1.JRE System Library主要存放J2SE的标准jar,一般不需要调整. 2.Referenced Libraries是存放第三方的j ...