图论dijkstra Bellman_Ford与Floyd算法的性质比较与实现

本文详细对比了Dijkstra、Bellman-Ford和Floyd三种经典的最短路径算法的特点及适用场景,并给出了每种算法的具体实现流程与时间复杂度。Dijkstra算法适用于非负边权值的图;Bellman-Ford算法支持带负权边但不含负权环的图;Floyd算法能够处理任意两点间最短路径问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dijkstra,Bellman_Ford,Floyd算法的比较:
:Dijkstra算法,图所有边权值都为非负的;
:Bellman_Ford算法,图中所有边权值可以存在负值,但是不能存在原点可达的负权回路,如果存在负权回路,该算法可以给出判断;
:Floyd算法,不允许所有权值为负的回路,可以求出任意两点间的最短距离,而Dijkstra和Bellman_Ford算法只可以求出任意点到达源点的最短距离;
:Dijkstra算法的思想是贪心,Bellman_Ford和Floyd算法的思想是动态规划
:三者:图中都可以出现正权回路

Bellman_Ford算法实现

时间复杂度O(nm)

1 #define INF 10000
2 queue<int>q;
3  bool inq[1000];//判断是否已经在队列中
4  for(int i=0;i<n;i++)
5 d[i]=INF;
6 d[0]=0;
7 memset(inq,false,sizeof(inq));
8 q.push(0);
9 inq[0]=true;
10  while(!q.empty())
11 {
12 int x=q.front();q.pop();
13 inq[x]=false;
14 for(int i=first[x];i!=NULL;i=next[i])//寻找所有与x相连的点
15   {
16 if(d[v[i]]>d[x]+w[i])//进行松弛操作
17   d[v[i]]=d[x]+w[i];
18 if(!inq[v[i]])
19 {
20 inq[v[i]]=true;
21 q.push(v[i]);
22 }
23 }
24 }

Floyed算法

时间复杂度O(n^3);
动态方程:
当k=0时:d[i][j]=w[i][j]
当k>=1时:d[i][j]=min(d[i][j],d[i][k]+d[k][j])

1 for(int k=0;k<n;k++)
2 for(int i=0;i<n;i++)
3 for(int j=0;j<n;j++)
4 if(d[i][k]+d[k][j]<d[i][j])
5 d[i][j]=d[i][k]+d[k][j]

Dijkstra算法伪代码及代码

从单个原点出发到所有节点的最短路径。该算法适用于有向图和无向图
初始化G,s
S=空
Q=V[G];
d=无穷
while(!Q.isempty())
{
在d中选出最小值对应的下标为u
 S=S+u
 Q=Q-u
 对于所有从u出发的边(u,y)更新d[y]=min{d[y],d[u]+map[u,y]};
 }
 利用father数组记录路径
 时间复杂度O(n*n)
 优化dijkstra算法为:dijkstra+优先队列 时间复杂度O(MlogN);

1 #include<iostream>
2 #include<queue>
3 usingnamespace std;
4 int G[12][12],E[12][12],d[12],mark[12],N,x,y,z;
5 /*
6 x为起点y为终点 z为距离
7 G存储图,E存储边,d存储距离,mark判断该点是否已经算过
8 */
9 struct node
10 {
11 int valu;
12 int index;
13 friend booloperator<(node a,node b)
14 {
15 return a.valu>b.valu;
16 }
17 }t,st;//重载运算符<
18 int main()
19 {
20 while(cin>>N)
21 {
22 for(int i=0;i<12;i++)
23 G[i][0]=0,d[i]=1000,mark[i]=0;//初始化
24 d[1]=0;
25 while(N--)
26 {
27 cin>>x>>y>>z;
28 G[x][++G[x][0]]=y;
29 E[x][++E[x][0]]=z;
30 }
31 priority_queue<node>q;//声明优先队列
32 t.valu=0,t.index=1;
33 q.push(t);
34 while(!q.empty())
35 {
36 t=q.top();
37 q.pop();
38 if(mark[t.index])//如果已经算过则跳过
39 continue;
40 mark[t.index]=1;
41 for(int i=1;i<=G[t.index][0];i++)
42 {
43 if(d[t.index]+E[t.index][i]<d[G[t.index][i]])//松弛操作
44 {
45 d[G[t.index][i]]=d[t.index]+E[t.index][i];
46 st.valu=d[G[t.index][i]];
47 st.index=G[t.index][i];
48 q.push(st);
49 }
50 }
51 }
52 cout<<"原点为1每一点到原点的最短距离为:"<<endl;
53 for(int i=1;i<6;i++)
54 cout<<d[i]<<"";
55 cout<<endl;
56 }
57 }
58 /*
59 9
60 1 2 10
61 1 3 3
62 2 3 1
63 3 2 4
64 2 4 2
65 3 4 8
66 3 5 2
67 4 5 7
68 5 4 9
69 */

转载于:https://www.cnblogs.com/penseur/archive/2011/03/01/1967944.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值