算法前提
- n,图的顶点数
- k,图的边数
- begin,起点下标
- end,终点下标
- map[ i ][ j ],图的存储数组
- low[ i ],图的最短路径状态数组
- visit[ i ],顶点访问标记数组
- INF,不可访问标记
算法描述
- 初始化最短距离为直接距离,low[ i ] = map[ begin ][ i ]
- 初始化访问标记,visit数组为false
- 查找未访问的low[ i ]的最小值,记录最小下标index,并记m_len=low[ index ],标记已访问visit[ index ] = true
- 检索每一个最短距离,如果从begin到index再到i的距离更短,则更新low[ i ] = m_len+map[ index ][ i ]
- 重复第3步,直到所有visit数组均为true
- low[ end ]为所求值
输入
- 第一行:图的顶点数n
- 第二行:图的边数k
- 第三行:算法起点begin,算法终点end
- 接下来为k行:
- 图的点a下标,图的点b下标,a到b的步长len
-
样例输入:
5
6
0 1
0 2 60
0 3 30
0 4 50
1 2 20
1 4 10
3 4 10
输出
50
代码
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 9999999 // 定义不可达
#define MAXN 200 // 最大顶点数
int begin_idx, end_idx, n, k, map[MAXN][MAXN], low[MAXN], visit[MAXN]; // low最短距离,visit访问标记
/*
5
6
0 1
0 2 60
0 3 30
0 4 50
1 2 20
1 4 10
3 4 10
*/
void dijkstra()
{
int m_len, index;
for (int i = 0; i < n; i++)
{
low[i] = map[begin_idx][i]; // 初始化low
}
for (int i = 0; i < n; i++)
{
m_len = INF;
index = i;
for (int j = 0; j < n; j++)
{ // 查找最短未访问距离
if (low[j] < m_len && !visit[j])
{
m_len = low[j];
index = j;
}
}
visit[index] = true;
for (int j = 0; j < n; j++)
{
int step_len = m_len + map[index][j];
if (step_len < low[j])
{ // 是否更新距离
low[j] = step_len;
visit[j] = false;
}
}
}
cout << low[end_idx] << endl;
}
int main()
{
int a, b, len;
cin >> n; // 顶点数
cin >> k; // 边数
cin >> begin_idx >> end_idx; // 始末下标
fill(low, low + MAXN, false);
fill(visit, visit + MAXN, false);
for (int i = 0; i < MAXN; i++)
{
fill(map[i], map[i] + MAXN, INF);
}
visit[begin_idx] = true;
for (int i = 0; i < k; i++)
{
cin >> a >> b >> len; // 输入边
map[a][b] = map[b][a] = len;
}
dijkstra();
return 0;
}