dijkstra算法1.Floyd算法(适用于没有负权回路)
特点:可以求任意两个点的最短路径
思想:
通过三个for循环 让任意一个点做借助点找到任意两个点之间的最短路径
所以计算量比较大,不适用于大规模的数据,时间复杂度n三次方
注意单向和双向的问题
2.dijkstra算法(Dijkstra算法仅适用于非负权重的图)
特点:从一个起点出发可以求该点到任意一个点的最短路径、
思想:
先从一个简单的问题入手:
求一个特定的点a到点s的距离:
代码:
#include <iostream>
#include <cstring>
using namespace std;
const int N=200,n=19;
int dist[N];
int g[N][N];
void add(char x,char y,int c)
{
int a=x-'A'+1;//ASCII码计算
int b=y-'A'+1;
g[a][b]=g[b][a]=c;//建一个无向图的临接矩阵
}
bool vis[N];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);//初始化
for (int i=1;i<=n;i++)
{ dist[i]=g[1][i]; //距离初始化
vis[i]=0; //vis初始化
}
dist[1]=0;
for(int i=0;i<n;i++)//循环直到所有顶点的最短路径都求出
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&(t==-1||dist[j]<dist[t]))//选取不在vis中且具有最小距离的顶点t
t=j;
}
vis[t]=1;//顶点t加入vis中
for(int j=1;j<=n;j++)//修改不在vis中的顶点的距离
{
if(vis[j]==0)
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
return dist[n];
}
int main()
{
memset(g,0x3f,sizeof g);
add('A','B',2);
add('A','C',1);
add('A','D',1);
add('A','D',1);
add('B','J',2);
add('B','G',1);
add('C','D',3);
add('C','F',3);
add('C','G',3);
add('D','E',1);
add('D','G',2);
add('D','H',1);
add('D','I',2);
add('E','H',1);
add('E','I',3);
add('F','G',1);
add('F','J',1);
add('G','F',1);
add('G','I',3);
add('G','K',2);
add('H','I',1);
add('H','L',2);
add('I','M',3);
add('J','S',2);
add('K','N',1);
add('K','L',3);
add('K','P',2);
add('L','M',1);
add('L','R',1);
add('M','N',2);
add('M','Q',1);
add('M','S',1);
add('N','P',1);
add('O','P',1);
add('O','Q',1);
add('O','R',3);
add('R','S',1);
cout<<dijkstra();
return 0;
}
核心的代码:
int dijkstra()
{
memset(dist,0x3f,sizeof dist);//初始化
for (int i=1;i<=n;i++)
{ dist[i]=g[1][i]; //距离初始化
vis[i]=0; //vis初始化
}
dist[1]=0;
for(int i=0;i<n;i++)//循环直到所有顶点的最短路径都求出
{
int t=-1;
for(int j=1;j<=n;j++)
{
if(!vis[j]&&(t==-1||dist[j]<dist[t]))//选取不在vis中且具有最小距离的顶点t
t=j;
}
vis[t]=1;//顶点t加入vis中,vis表示该点已经找到到a点的最短路径
for(int j=1;j<=n;j++)//修改不在vis中的顶点的距离
{
if(vis[j]==0)
dist[j]=min(dist[j],dist[t]+g[t][j]);
}
}
return dist[n];
}
通俗来说就是第一轮大循环先找到跟a点直接相连的点,并把其中最短的点标记一下,然后通过该点为跳板更新更新与这个点直接相连(可能在前几次循环是直接相连的,但是到了循环后期就不一定是直接相连而是这两个点的距离已知)的点到a点的最短距离,然后开始后面的几轮大循环,a点到各个点的最短距离也就会浮出水面。