Who's Studio.

hihoCoder#1089 - Floyd算法

Word count: 388Reading time: 2 min
2016/05/16

题目

给定一个无向图,两个顶点之间可能有多条边,求任意两个顶点之间的最短路径。
具体描述请见hihoCoder

解题思路

经典的Floyd算法。采用动态规划的思想,假设d[i, j]是从i到j的距离,且路径允许经过的节点数慢慢增加。写成递推式就是
d[i, j] = min(d[i, j], d[i, k] + d[k, j])

时间复杂度

时间复杂度为N3,空间复杂度为N2

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void floyd(int** graph, int N) {
for (int k = 1; k <= N; k++) {
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++) {
if (graph[i][k] != -1 && graph[k][j] != -1) {
if (graph[i][j] == -1)
graph[i][j] = graph[i][k] + graph[k][j];
else
graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]);
}
}
}
}

int main() {
int N = 0, M = 0;
cin >> N >> M;
int** graph = new int*[N + 1];
for (int i = 1; i < N + 1; i++) {
graph[i] = new int[N + 1];
for (int j = 1; j < N + 1; j++)
graph[i][j] = -1;
graph[i][i] = 0;
}
for (int i = 0; i < M; i++) {
int a = 0, b = 0, edge = 0;
cin >> a >> b >> edge;
if (graph[a][b] == -1) {
graph[a][b] = edge;
graph[b][a] = edge;
}
else if (graph[a][b] > edge) {
graph[a][b] = edge;
graph[b][a] = edge;
}
}

floyd(graph, N);
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= N; j++)
cout << graph[i][j] << " ";
cout << endl;
}

for (int i = 1; i < N + 1; i++)
delete[] graph[i];
delete[] graph;

return 0;
}
CATALOG
  1. 1. 题目
  2. 2. 解题思路
  3. 3. 时间复杂度
  4. 4. 代码