You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
// Dijkstra算法(记录路径)
|
|
|
|
|
// https://blog.csdn.net/renzijing/article/details/80572549
|
|
|
|
|
// https://blog.csdn.net/lbperfect123/article/details/84281300
|
|
|
|
|
//正无穷
|
|
|
|
|
const int INF = 9999;
|
|
|
|
|
//声明数据的最大维度
|
|
|
|
|
const int N = 100;
|
|
|
|
|
|
|
|
|
|
int n, m;
|
|
|
|
|
|
|
|
|
|
//初始数据
|
|
|
|
|
int mapp[N][N];
|
|
|
|
|
|
|
|
|
|
bool visited[N];
|
|
|
|
|
//距离,就是从1号顶点到其余各个顶点的初始路程
|
|
|
|
|
int dist[N];
|
|
|
|
|
|
|
|
|
|
//与求最短路相比,增加一个path数组,来记录最短路的路径,先将path[i]=-1,之后每次找出最短路的点p后将path[j]=p,用path[j]=i表示从i到j最短路的路径
|
|
|
|
|
int path[N];
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:迪杰斯特拉算法
|
|
|
|
|
* 试题板子
|
|
|
|
|
* @param v 计算哪个节点做为起始点到各节点的距离
|
|
|
|
|
*/
|
|
|
|
|
void Dijkstra(int v) {
|
|
|
|
|
//初始化
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
dist[i] = mapp[v][i];
|
|
|
|
|
visited[i] = 0;
|
|
|
|
|
path[i] = -1;
|
|
|
|
|
}
|
|
|
|
|
visited[v] = 1;
|
|
|
|
|
for (int i = 1; i <= n; i++) {
|
|
|
|
|
int p, minn = INF;
|
|
|
|
|
for (int j = 1; j <= n; j++) {
|
|
|
|
|
if (!visited[j] && dist[j] < minn) {
|
|
|
|
|
p = j;
|
|
|
|
|
minn = dist[j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
visited[p] = 1;
|
|
|
|
|
for (int j = 1; j <= n; j++) {
|
|
|
|
|
if (!visited[j] && dist[p] + mapp[p][j] < dist[j]) {
|
|
|
|
|
dist[j] = dist[p] + mapp[p][j];
|
|
|
|
|
path[j] = p;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:输出路径
|
|
|
|
|
* @param s 起点
|
|
|
|
|
* @param n 节点数量
|
|
|
|
|
*/
|
|
|
|
|
void print(int s, int n) {
|
|
|
|
|
stack<int> q;
|
|
|
|
|
for (int i = 2; i <= n; i++) {
|
|
|
|
|
int p = i;
|
|
|
|
|
while (path[p] != -1) {
|
|
|
|
|
q.push(p);
|
|
|
|
|
p = path[p];
|
|
|
|
|
}
|
|
|
|
|
q.push(p);
|
|
|
|
|
cout << s << "-->" << i << " ";
|
|
|
|
|
cout << "dis" << ":" << dist[i] << " ";
|
|
|
|
|
cout << s;
|
|
|
|
|
while (!q.empty()) {
|
|
|
|
|
cout << "-->" << q.top();
|
|
|
|
|
q.pop();
|
|
|
|
|
}
|
|
|
|
|
cout << endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
//输入+输出重定向
|
|
|
|
|
freopen("../MiniPath/Dijkstra.txt", "r", stdin);
|
|
|
|
|
|
|
|
|
|
//n表示结点的个数,m表示路径的数目
|
|
|
|
|
while (cin >> n >> m) {
|
|
|
|
|
// 多组数据输入,以 0 0为结束条件
|
|
|
|
|
if (n == 0 && m == 0) break;
|
|
|
|
|
|
|
|
|
|
//1、初始化二维数组,全部为一个非常大的数据
|
|
|
|
|
for (int i = 0; i <= n; i++) {
|
|
|
|
|
for (int j = 0; j <= n; j++) {
|
|
|
|
|
mapp[i][j] = INF;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//2、s表示路径的起点,t表示路径的终点,edge表示该路径的长度。
|
|
|
|
|
int s, t, edge;
|
|
|
|
|
//录入路径
|
|
|
|
|
while (m--) {
|
|
|
|
|
cin >> s >> t >> edge;
|
|
|
|
|
//将权写入
|
|
|
|
|
mapp[s][t] = edge;
|
|
|
|
|
mapp[t][s] = edge; //双向写入,就是表示无向图
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//3、调用核心算法: 源点(统一规定为v1)到所有其他各定点的最短路径长度。
|
|
|
|
|
Dijkstra(1);
|
|
|
|
|
|
|
|
|
|
//输出结果
|
|
|
|
|
print(1, n);
|
|
|
|
|
}
|
|
|
|
|
//关闭文件
|
|
|
|
|
fclose(stdin);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|