Files
python/TangDou/MiniPath/Dijkstra2.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

119 lines
3.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
// dijkstra算法模板及其用法
// https://www.cnblogs.com/yoyo-sincerely/p/6400906.html
// https://www.cnblogs.com/mycapple/archive/2012/08/12/2634227.html
/***************************************
* About: 有向图的Dijkstra算法实现
* Author: Tanky Woo
* Blog: www.WuTianQi.com
***************************************/
const int maxnum = 100;
const int maxint = 999999;
// 各数组都从下标1开始
int dist[maxnum]; // 表示当前点到源点的最短路径长度
int prevArr[maxnum]; // 记录当前点的前一个结点
int c[maxnum][maxnum]; // 记录图的两点间路径长度
int n, line; // 图的结点数和路径数
void Dijkstra(int n, int v, int *dist, int *prev, int c[maxnum][maxnum]) {
bool s[maxnum]; // 判断是否已存入该点到S集合中
for (int i = 1; i <= n; ++i) {
dist[i] = c[v][i];
s[i] = 0; // 初始都未用过该点
if (dist[i] == maxint)
prev[i] = 0;
else
prev[i] = v;
}
dist[v] = 0;
s[v] = 1;
// 依次将未放入S集合的结点中取dist[]最小值的结点放入结合S中
// 一旦S包含了所有V中顶点dist就记录了从源点到所有其他顶点之间的最短路径长度
for (int i = 2; i <= n; ++i) {
int tmp = maxint;
int u = v;
// 找出当前未使用的点j的dist[j]最小值
for (int j = 1; j <= n; ++j)
if ((!s[j]) && dist[j] < tmp) {
u = j; // u保存当前邻接点中距离最小的点的号码
tmp = dist[j];
}
s[u] = 1; // 表示u点已存入S集合中
// 更新dist
for (int j = 1; j <= n; ++j)
if ((!s[j]) && c[u][j] < maxint) {
int newdist = dist[u] + c[u][j];
if (newdist < dist[j]) {
dist[j] = newdist;
prev[j] = u;
}
}
}
}
void searchPath(int *prev, int v, int u) {
int que[maxnum];
int tot = 1;
que[tot] = u;
tot++;
int tmp = prev[u];
while (tmp != v) {
que[tot] = tmp;
tot++;
tmp = prev[tmp];
}
que[tot] = v;
for (int i = tot; i >= 1; --i)
if (i != 1)
cout << que[i] << " -> ";
else
cout << que[i] << endl;
}
int main() {
freopen("../MiniPath/Dijkstra2.txt", "r", stdin);
// 各数组都从下标1开始
// 输入结点数
cin >> n;
// 输入路径数
cin >> line;
int p, q, len; // 输入p, q两点及其路径长度
// 初始化c[][]为maxint
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
c[i][j] = maxint;
for (int i = 1; i <= line; ++i) {
cin >> p >> q >> len;
if (len < c[p][q]) // 有重边
{
c[p][q] = len; // p指向q
c[q][p] = len; // q指向p这样表示无向图
}
}
for (int i = 1; i <= n; ++i)
dist[i] = maxint;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j)
printf("%8d", c[i][j]);
printf("\n");
}
Dijkstra(n, 1, dist, prevArr, c);
// 最短路径长度
cout << "源点到最后一个顶点的最短路径长度: " << dist[n] << endl;
// 路径
cout << "源点到最后一个顶点的路径为: ";
searchPath(prevArr, 1, n);
}