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
using
namespace
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
bool
operator
<
(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
*/