目录:
最短路径简介:
最短路径问题是图论研究中的一个经典算法问题, 旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。 算法具体的形式包括:
(1)确定起点的最短路径问题( 即已知起始结点),求最短路径的问题。
(2)确定终点的最短路径问题(与确定起点的问题相反),该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
(3)确定起点终点的最短路径问题 - 即已知起点和终点,求两结点之间的最短路径。
(4)全局最短路径问题 - 求图中所有的最短路径。
解决最短路径问题有 5 种主流的算法:Floyd算法 \ Floyd-warshall算法,Dijkstra算法,Bellman-Ford算法 \ SPFA算法,Johnson算法,A*算法。
Floyd算法 \ Floyd-warshall算法:
Floyd算法 和 Floyd-warshall算法 实际上是一个东西,只不过是名字不同罢了。
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法类似。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授 罗伯特·弗洛伊德 命名。
Floyd算法的边权值可正可负,但需要使用邻接矩阵存储图的边权值。
时间复杂度:O()
【代码实现】
//假设有n个点,m条边,求1~n的最短路径
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<string>
#include<cstring>
#include<queue>//头文件
using namespace std;
int n,m;
int mapp[1001][1001];
int clean()//初始化
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==j)
{
mapp[i][j]=0;
}
else
{
mapp[i][j]=0x7f7f7f;
//mapp[i][j]=- 0x7f7f7f;
//初始为无穷大或无穷小,需要根据题目变通
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);//读入
clead();//初始化
for(int i=1;i<=m;i++)//读入边的值
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
mapp[u][v]=w;//有向图
//mapp[u][v]=mapp[v][u]=w;无向图
}
for(int k=1;k<=n;k++)//Floyd算法模板
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(mapp[i][k]+mapp[k][j]<mapp[i][j])
{