数据结构:点之间的最短距离--Floyd算法
Floyd算法
Floyd算法
Dijkstra算法是用于解决单源最短路径问题的,Floyd算法则是解决点对之间最短路径问题的。Floyd算法的设计策略是动态规划,而Dijkstra採取的是贪心策略。当然,贪心算法就是动态规划的特例。
算法思想
点对之间的最短路径仅仅会有两种情况:
- 两点之间有边相连。weight(Vi,Vj)即是最小的。
- 通过还有一点:中介点,两点相连,使weight(Vi,Vv)+weight(Vv,Vj)最小。
故当Vv取全然部顶点后,Distance(Vi,Vj)就可以达到最小。Floyd算法的起点就是图的邻接矩阵。
思想极难得到,而有了思想,稍加经验就可以写出代码。向思想的开创者致敬。
代码
#include<iostream>
#include<iomanip>
#include<stack>
using namespace std;
#define MAXWEIGHT 100
#undef INFINITY
#define INFINITY 1000
class Graph
{
private:
//顶点数
int numV;
//边数
int numE;
//邻接矩阵
int **matrix;
public:
Graph(int numV);
//建图
void createGraph(int numE);
//析构方法
~Graph();
//Floyd算法
void Floyd();
//打印邻接矩阵
void printAdjacentMatrix();
//检查输入
bool check(int, int, int);
};
类实现
//构造函数,指定顶点数目
Graph::Graph(int numV)
{
//对输入的顶点数进行检測
while (numV <= 0)
{
cout << "顶点数有误! 又一次输入 ";
cin >> numV;
}
this->numV = numV;
//构建邻接矩阵。并初始化
matrix = new int*[numV];
int i, j;
for (i = 0; i < numV; i++)
matrix[i] = new int[numV];
for (i = 0; i < numV; i++)
for (j = 0; j < numV; j++)
{
if (i == j)
matrix[i][i] = 0;
else
matrix[i][j] = INFINITY;
}
}
void Graph::createGraph(int numE)
{
/*
对输入的边数做检測
一个numV个顶点的有向图,最多有numV*(numV - 1)条边
*/
while (numE < 0 || numE > numV*(numV - 1))
{
cout << "边数有问题!又一次输入 ";
cin >> numE;
}
this->numE = numE;
int tail, head, weight, i;
i = 0;
cout << "输入每条边的起点(弧尾)、终点(弧头)和权值" << endl;
while (i < numE)
{
cin >> tail >> head >> weight;
while (!check(tail, head, weight))
{
cout << "输入的边不对!请又一次输入 " << endl;
cin >> tail >> head >> weight;
}
matrix[tail][head] = weight;
i++;
}
}
Graph::~Graph()
{
int i;
for (i = 0; i < numV; i++)
delete[] matrix[i];
delete[]matrix;
}
/*
弗洛伊德算法
求各顶点对之间的最短距离
及其路径
*/
void Graph::Floyd()
{
//为了不改动邻接矩阵,多用一个二维数组
int **Distance = new int*[numV];
int i, j;
for (i = 0; i < numV; i++)
Distance[i] = new int[numV];
//初始化
for (i = 0; i < numV; i++)
for (j = 0; j < numV; j++)
Distance[i][j] = matrix[i][j]; //prev数组
int **prev = new int*[numV];
for (i = 0; i < numV; i++)
prev[i] = new int[numV];
//初始化prev
for (i = 0; i < numV; i++)
for (j = 0; j < numV; j++)
{
if (matrix[i][j] == INFINITY)
prev[i][j] = -1;
else
prev[i][j] = i;
} int d, v;
for (v = 0; v < numV; v++)
for (i = 0; i < numV; i++)
for (j = 0; j < numV; j++)
{
d = Distance[i][v] + Distance[v][j];
if (d < Distance[i][j])
{
Distance[i][j] = d;
prev[i][j] = v;
}
}
//打印Distance和prev数组
cout << "Distance..." << endl;
for (i = 0; i < numV; i++)
{
for (j = 0; j < numV; j++)
cout << setw(3) << Distance[i][j];
cout << endl;
}
cout << endl << "prev..." << endl;
for (i = 0; i < numV; i++)
{
for (j = 0; j < numV; j++)
cout << setw(3) << prev[i][j];
cout << endl;
}
cout << endl;
//打印顶点对最短路径
stack<int> s;
for (i = 0; i < numV; i++)
{
for (j = 0; j < numV; j++)
{
if (Distance[i][j] == 0);
else if (Distance[i][j] == INFINITY)
cout << "顶点 " << i << " 到顶点 " << j << " 无路径! " << endl;
else
{
s.push(j);
v = j;
do{
v = prev[i][v];
s.push(v);
} while (v != i);
//打印路径
cout << "顶点 " << i << " 到顶点 " << j << " 的最短路径长度是 "
<< Distance[i][j] << " ,其路径序列是...";
while (!s.empty())
{
cout << setw(3) << s.top();
s.pop();
}
cout << endl;
}
}
cout << endl;
}
//释放空间
for (i = 0; i < numV; i++)
{
delete[] Distance[i];
delete[] prev[i];
}
delete[]Distance;
delete[]prev;
}
//打印邻接矩阵
void Graph::printAdjacentMatrix()
{
int i, j;
cout.setf(ios::left);
cout << setw(7) << " ";
for (i = 0; i < numV; i++)
cout << setw(7) << i;
cout << endl;
for (i = 0; i < numV; i++)
{
cout << setw(7) << i;
for (j = 0; j < numV; j++)
cout << setw(7) << matrix[i][j];
cout << endl;
}
}
bool Graph::check(int tail, int head, int weight)
{
if (tail < 0 || tail >= numV || head < 0 || head >= numV
|| weight <= 0 || weight >= MAXWEIGHT)
return false;
return true;
}
主函数
int main()
{
cout << "******Floyd***by David***" << endl;
int numV, numE;
cout << "建图..." << endl;
cout << "输入顶点数 ";
cin >> numV;
Graph graph(numV);
cout << "输入边数 ";
cin >> numE;
graph.createGraph(numE);
cout << endl << "Floyd..." << endl;
graph.Floyd();
system("pause");
return 0;
}
执行
小结
若有所帮助,顶一个哦。
专栏文件夹:
版权声明:本文博主原创文章。转载,转载请注明出处。
数据结构:点之间的最短距离--Floyd算法的更多相关文章
- 深度解析(一六)Floyd算法
Floyd算法(一)之 C语言详解 本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德 ...
- 【Aizu - 0189】Convenient Location (最短路 Floyd算法)
Convenient Location 直接翻译了 Descriptions 明年毕业的A为就业而搬家.就职的公司在若干城市都有办公室,不同天出勤的办公室也不同.所以A在考虑住在哪去各个办公室的时长最 ...
- 数据结构与算法——弗洛伊德(Floyd)算法
介绍 和 Dijkstra 算法一样,弗洛伊德(Floyd)算法 也是一种用于寻找给定的加权图中顶点间最短路径的算法.该算法名称以创始人之一.1978 年图灵奖获得者.斯坦福大学计算机科学系教授罗伯特 ...
- _DataStructure_C_Impl:Floyd算法求有向网N的各顶点v和w之间的最短路径
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef char VertexType[4] ...
- Floyd算法——计算图中任意两点之间的最短路径
百度百科定义:传送门 一.floyd算法 说实话这个算法是用来求多源最短路径的算法. 算法原理: 1,从任意一条单边路径开始.所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大. 2,对 ...
- 数据结构与算法--最短路径之Floyd算法
数据结构与算法--最短路径之Floyd算法 我们知道Dijkstra算法只能解决单源最短路径问题,且要求边上的权重都是非负的.有没有办法解决任意起点到任意顶点的最短路径问题呢?如果用Dijkstra算 ...
- 最短路径—Dijkstra算法和Floyd算法
原文链接:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最后边附有我根据文中Dijkstra算法的描述使用jav ...
- floyd算法小结
floyd算法是被大家熟知的最短路算法之一,利用动态规划的思想,f[i][j]记录i到j之间的最短距离,时间复杂度为O(n^3),虽然时间复杂度较高,但是由于可以处理其他相似的问题,有着广泛的应用,这 ...
- Floyd算法(三)之 Java详解
前面分别通过C和C++实现了弗洛伊德算法,本文介绍弗洛伊德算法的Java实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3. 弗洛伊德算法的代码说明 4. 弗洛伊德算法的源码 转载请注明 ...
随机推荐
- [Vue] Load components when needed with Vue async components
In large applications, dividing the application into smaller chunks is often times necessary. In thi ...
- 使用Perl合并文件
使用Perl合并文件 有时需要将整个目录下的小文件合并到一个文件中,以便查阅检索 特性 整个目录完全遍历,自动存入单个文件 顺序遍历文件 待合并的目录 合并后的文件内容 syscfg/test1 sy ...
- ZOJ 2476 Total Amount 字符串
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1476 题目大意: 给你n串数字组成的字符串,要求输出他们相加的和. 如:n= ...
- 经验总结56--mybatis返回主键
使用mybatis框架时,有时候须要新插入的数据的主键是多少. 1.oracle 因为oracle是建的序列文件,获取ID值. <insert id="insert" par ...
- div宽度设置width:100%后再设置padding或margin超出父元素的解决办法
div宽度设置width:100%后再设置padding或margin超出父元素的解决办法 一.总结 一句话总结:直接加上box-sizing:border-box;即可解决上述问题. 1.box-s ...
- 在ArcEngine中使用Geoprocessing工具-执行工具
转自原文在ArcEngine中使用Geoprocessing工具-执行工具 来解析一下Geoprocessor类的Execute方法,他有两种重载,Execute(IGPProcess, ITrack ...
- Java验证是否为纯数字
package rbq.codedemo; import java.util.regex.Pattern; /** * Created by rbq on 2016/12/13. */ public ...
- web网站如何实现兼容手机
web网站如何实现兼容手机 一.总结 一句话总结:加上这句话即可:<meta name="viewport" content="width=device-width ...
- 【机器学习实战】第2章 k-近邻算法(kNN)
第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法主要是用来进行分类的. KNN 场景 电影可以按照题材分类,那么如何区分 动作片 和 爱情片 呢? 动作 ...
- 【前端统计图】echarts实现单条折线图
五分钟上手: 图片.png <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...