C++数据结构——旅游规划(Floyd算法详解)
旅游规划
作者 陈越 单位 浙江大学
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输出样例:
3 40
代码长度限制 16 KB Java (javac) 时间限制 800 ms 内存限制 64 MB
其他编译器 时间限制 400 ms内存限制 64 MB
解题代码
#include<bits/stdc++.h>
using namespace std;
#define MAX 100000
int main()
{int n,m,s,d;int go,to,len,cost;int val[505][505];int dist[505][505];while(cin>>n>>m>>s>>d){for(int i=0;i<n;i++){for(int j=0;j<n;j++){val[i][j]=MAX;dist[i][j]=MAX;}}for(int i=1;i<=m;i++){cin>>go>>to>>len>>cost;val[go][to]=cost;val[to][go]=cost;dist[go][to]=len;dist[to][go]=len;}for(int i=0;i<n;i++){for(int j=0;j<n;j++){for(int k=0;k<n;k++){if(dist[i][j]>dist[i][k]+dist[k][j]){dist[i][j]=dist[i][k]+dist[k][j];val[i][j]=val[i][k]+val[k][j];}else if(dist[i][j]==dist[i][k]+dist[k][j]){if(val[i][j]>val[i][k]+val[k][j]){val[i][j]=val[i][k]+val[k][j];}}}}}cout<<dist[s][d]<<" "<<val[s][d]<<endl;}
}
解题思路
首先介绍一下Floyd算法
通过一个图的权值矩阵求出它的每两点间的最短路径矩阵。
从图的带权邻接矩阵A=[a(i,j)] n×n开始,迭代地进行n次更新,即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
采用松弛技术(松弛操作),对在i和j之间的所有其他点进行一次松弛。所以时间复杂度为O(n^3);
以上内容来自百度词条,看不懂没关系,总的来说,Floyd算法的时间复杂度是O(n^3),它能够计算任意两点之间的最短路径,利用动态规划的思想。我们根据题目去学习一下这个算法。
首先,我们先根据样例绘画出我们的图,如下所示:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
我们要求的是0到3的最短路径,然后这里要注意,如果路径相同,要选最便宜的一条路径。
然后根据题目,我们可以得到下面这两个邻接矩阵,dist是代表点与点之间的路径,val代表点之间需要花费的价钱,INF代表无穷大
dist | 0 | 1 | 2 | 3 |
---|---|---|---|---|
0 | INF | 1 | 2 | 4 |
1 | 1 | INF | INF | 2 |
2 | 2 | INF | INF | 1 |
3 | 4 | 2 | 1 | INF |
val | 0 | 1 | 2 | 3 |
---|---|---|---|---|
0 | INF | 20 | 20 | 10 |
1 | 20 | INF | INF | 30 |
2 | 20 | INF | INF | 20 |
3 | 10 | 30 | 20 | INF |
Floyd算法就是求任意两点,找这两点之间是否存在一点或者多点作为中介点,能够得到两点间的最短路径。只不过这道题目我们还要考虑路径相同的情况下,要选择价值比较小的那条路径。
本题解题核心代码
for(int i=0;i<n;i++){//以i为起点for(int j=0;j<n;j++){//为终点for(int k=0;k<n;k++){//k为中间媒介点//如果邻接表中此时存的i到j的路径大于以k作为媒介点的路径,那么更改i到j的距离,并且更改花费if(dist[i][j]>dist[i][k]+dist[k][j]){dist[i][j]=dist[i][k]+dist[k][j];val[i][j]=val[i][k]+val[k][j];//如果距离相等,那就判断价值是否小于已存在矩阵中的价值,是则替换价值}else if(dist[i][j]==dist[i][k]+dist[k][j]){if(val[i][j]>val[i][k]+val[k][j]){val[i][j]=val[i][k]+val[k][j];}}}}
}
最好的理解办法就是解析循环,第一层循环就是表示以i为起点,第二层循环表示的是以j为起点,第三层循环表示的从i到j是否存在一个点k能够作为中介点,令i到j的距离更短。
假设当i=0时,循环j=1(j=0时找0到0的距离,没意义,不举例了)然后我们找k,k=0和k=1其实没啥意义,我们从k=2开始。
其实我们可以得到这样的图:
实际上就是找比较0到1的直接距离,和0到2再到1的距离进行比较,如果短就先存到邻接矩阵里面,也就是这句代码
if(dist[i][j]>dist[i][k]+dist[k][j]){dist[i][j]=dist[i][k]+dist[k][j];val[i][j]=val[i][k]+val[k][j];
}
其他的点也是如此类推,假设,我们假设0到2再到1的距离比0到1的短,那么dist[0][1]=dist[0][2]+dist[2][1],然后再去判断将点3作为中间媒介点时,距离是否更短,短的话替换就行。
差不多就是这个道理吧,将点之间的最短距离存储再矩阵里,然后使用的时候直接矩阵中可以取出来用。
C++数据结构——旅游规划(Floyd算法详解)相关推荐
- 【最短路径Floyd算法详解推导过程】看完这篇,你还能不懂Floyd算法?还不会?...
简介 Floyd-Warshall算法(Floyd-Warshall algorithm),是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似.该算法名称以 ...
- 最短路径问题---Floyd算法详解
前言 Genius only means hard-working all one's life. Name:Willam Time:2017/3/8 1.最短路径问题介绍 问题解释: 从图中的某个顶 ...
- [数据结构]模式匹配算法--KMP算法详解
目录 一. 模式匹配 二. 模式匹配算法 1. 朴素模式匹配算法 2. KMP算法 1). KMP算法的优势 2). KMP算法的原理 3). next数组的构造 4). 利用next数组匹配的过程 ...
- “chaos”的算法--之Floyd算法详解(求最短路径)
倘若我们要在计算机上建立一个交通咨询系统则可以采用图的结构来表示实际的交通网络.其实现最基本的功能,求出任意两点间的最短路径, 求最短路径的经典方法有很多种,最常用的便是迪杰斯特拉算法和佛洛依德(Fl ...
- 弗洛伊德(Floyd)算法详解
Floyd 算法是解决图论问题的比较经典的算法,用来求解赋权图中每对顶点间的最短距离.当然,在求距离的过程中也可以得到最短距离的路径.这个算法与迪杰斯特拉(Dijkstra)算法相似,他们两个都属于最 ...
- Dijkstra算法和Floyd算法详解(MATLAB代码)
一.Dijkstra算法 1.算法简介 Dijkstra算法是由E.W.Dijkstra于1959年提出,又叫迪杰斯特拉算法,它应用了贪心算法模式,是目前公认的最好的求解最短路径的方法.算法解决的是有 ...
- 数据结构的六大排序算法详解
文章目录 一.简单排序 1.Comparable接口介绍 2.冒泡排序 3.选择排序 4.插入排序 二.高级排序 1.希尔排序 2.归并排序 3.快速排序 4.排序的稳定性 一.简单排序 在我们的程序 ...
- 数据结构进阶 八大排序算法详解
数据结构就是定义出某种结构:像数组结构.链表结构.树形结构等,实现数据结构就是我们主动去管理增删查改的实现函数 排序的概念 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列 ...
- 2019matlab中的floyd,基于matlab的floyd算法详解
function [d,path]=floyd(a,sp,ep) % floyd - 最短路问题 % % Syntax: [d,path]=floyd(a,sp,ep) % % Inputs: % ...
最新文章
- Kali Linux攻防系统(三:在Kali Linux系统中配置安全测试浏览器及系统清理备份)
- tensorflow.unstack() and tensorflow.stack()
- *Boosting*笔记
- leetcode算法题--划分为k个相等的子集★
- boost::phoenix::find相关的测试程序
- java 命令读取参数_如何读取/处理命令行参数?
- python显示图像某列的颜色值_Python Pandas Matplotlib图由单列中定义的类型值着色
- 有c基础学java多久_有c十十基础的自学java语言每天6小时要多长时间?
- LeetCode 348. 判定井字棋胜负(计数)
- 让皮肤美白细致的七大DIY - 生活至上,美容至尚!
- (转)Apache 中 KeepAlive 配置的合理使用
- linux系统添加环境变量
- 【css】适配iphoneX
- python iterableiterator
- (摘要)100个伟大的商业理念:理念35:引爆流行
- Quartz-第四篇 常规quartz的使用
- 微博开放平台注册应用
- ChinaVis 2017
- webpack 环境变量
- 洛谷 P1007 独木桥