mysql 最短路经_最短路径四种解法

本文详细介绍了图论中最短路径问题的四种经典算法:弗洛伊德算法、迪杰斯特拉算法、贝尔曼·福特算法以及SPFA算法。这四种算法分别在不同的场景下有着不同的效率和适用性,例如弗洛伊德适用于多源无负权边的情况,而迪杰斯特拉和贝尔曼·福特则适用于单源路径寻找,其中贝尔曼·福特还能处理负权边。文章通过C++代码实例展示了每种算法的工作原理和实现过程。
摘要由CSDN通过智能技术生成

最短路径四种解法

最短路径的四种解法

在学习“图”的时候,遇到过一道经典的题:最短路径。最短路径有四种最经典的解法。废话不多说,直接上代码。

弗洛伊德算法

//Floyd-Warshall

#include

using namespace std;

const int M=999999;

int n,m,p1,p2,l;

int map[1000][1000];

int main()

{

cin>>n>>m;

for (int i=1;i<=n;i++)

{

for (int j=1;j<=n;j++)

{

if (i==j)

{

map[i][j]=0;

}

else

{

map[i][j]=M;

}

}

}

for (int i=1;i<=m;i++)

{

cin>>p1>>p2>>l;

map[p1][p2]=l;

}

for (int k = 1; k <= n; k++) {

for (int i = 1; i <= n; i++) {

for (int j = 1; j <= n; j++) {

if (map[i][j] > map[i][k] + map[k][j]) {

map[i][j] = map[i][k] + map[k][j];

}

}

}

}

for (int i=1;i<=n;i++)

{

for (int j=1;j<=n;j++)

{

cout<

}

cout<

}

return 0;

}

弗洛伊德算法的时间复杂度O(n³),多源、无负权边,时效性较差。

迪杰斯特拉

//Dijkstra

#include

using namespace std;

const int M=99999999;

int n,m,p1,p2,l,map[100][100],dis[1000],book[1000]={0},mi,u;

int main()

{

cin>>n>>m;

for (int i=1;i<=n;i++)

{

for (int j=1;j<=n;j++)

{

if (i==j)

{

map[i][j]=0;

}

else

{

map[i][j]=M;

}

}

}

for (int i=1;i<=m;i++)

{

cin>>p1>>p2>>l;

map[p1][p2]=l;

}

book[1]=1;

for (int i=1;i<=n;i++)

{

dis[i]=map[1][i];

}

for (int i=1;i<=n-1;i++)

{

mi=M;

for (int j=1;j<=n;j++)

{

if (dis[j]

{

mi=dis[j];

u=j;

}

}

book[u]=1;

for (int k=1;k<=n;k++)

{

if(map[u][k]

{

if (dis[k]>dis[u]+map[u][k])

{

dis[k]=dis[u]+map[u][k];

}

}

}

}

for (int i=1;i<=n;i++)

{

cout<

}

return 0;

}

迪杰斯特拉的时间复杂度O(n²),单源、无负权,时效性较好。

贝尔曼·福特

//Bellman-Ford

#include

using namespace std;

const int M=9999999;

int main()

{

int n,m;

cin>>n>>m;

int p1[100],p2[100],l[100];

int dis[1000];

for (int i=1;i<=m;i++)

{

cin>>p1[i]>>p2[i]>>l[i];

}

for (int i=1;i<=n;i++)

{

dis[i]=M;

}

dis[1]=0;

for (int i=1;i<=n-1;i++)

{

for (int j=1;j<=m;j++)

{

if (dis[p2[i]]>dis[p1[i]]+l[i])

{

dis[p2[i]]=dis[p1[i]]+l[i];

}

}

}

for (int i=1;i<=n;i++)

{

cout<

}

return 0;

}

贝尔曼·福特的时间复杂度O(n²),单源、可以判断是否为负权,时效性较好。

SPFA-贝尔曼·福特队列优化

//SPFA

#include

using namespace std;

const int inf=9999999;

int main()

{

int n,m;

cin>>n>>m;

int p1[1000],p2[1000],l[1000];

int dis[1000];

int book[1000];

int first[1000];

int next[1000];

int que[1000]={0};

int tail=1,head=1;

int k;

for (int i=1;i<=n;i++)

{

dis[i]=inf;

}

dis[1]=0;

for (int i=1;i<=n;i++)

{

book[i]=0;

}

for (int i=1;i<=n;i++)

{

first[i]=-1;

}

int i;

for (i=1;i<=m;i++)

{

cin>>p1[i]>>p2[i]>>l[i];

next[i]=first[p1[i]];

first[p1[i]]=i;

}

que[tail]=1;

tail++;

book[i]=1;

while (head

{

k=first[que[head]];

while(k!=1)

{

if (dis[p2[k]]>dis[p1[k]]+l[k])

{

dis[p2[k]]=dis[p1[k]]+l[k];

}

if (book[p2[k]]==0)

{

que[tail]=p2[k];

tail++;

book[p2[k]]=1;

}

}

k=next[k];

head++;

}

for (i=1;i<=n;i++)

{

cout<

}

return 0;

}

贝尔曼·福特队列优化的时间复杂度最大为O(nm),最小为O(n),单源、可以判断是否为负权,时效性相对好。 本文结束了,点个赞再走呗o( ̄▽ ̄)ブ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值