#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<vector>
const int maxn = 1010;
#define inf 0x1f1f1f1f
using namespace std;
//struct Edges {
// int start,end, w; //边的起点,终点,权值
//};
struct mygraph{
// vexs[maxn]; //顶点数组
int vexnums; //顶点个数
int edgenums; //边数
int matrix[maxn][maxn]; //邻接矩阵
}mat;
void Dijkstra(int u, int v)
{
int val = u; //记录上一个节点
int pathmin[maxn]; //存放u节点到各节点之间的最短路径
int vis[maxn]; //存储最短路径的上一个节点,以便于等会输出路径
int visited[maxn]; //记录节点是非被访问过
memset(vis, -1, sizeof(vis));
//vis[u] = -1; //这里设置一个不可能的值作为等会输出的出口
memset(visited, 0, sizeof(visited));
visited[u] = 1; //将起始点设置为已访问
for (int i = 0; i < mat.vexnums; ++i)
{
pathmin[i] = mat.matrix[u][i]; //将u源点与其他各顶点的距离放入pathmin
}
pathmin[u] = 0; //自己到自己距离为0
for (int i = 0; i < mat.vexnums; ++i)
{
int minnum = inf, k;
for (int j = 0; j < mat.vexnums; ++j) //找到起始点u到其他节点的最短路径
{
if (visited[j]!=1&&pathmin[j] < minnum) {
k = j;
minnum = pathmin[j];
if(val==u) vis[j] = val; //记录起点为原点
}
}
visited[k] = 1;
val = k;
for (int j = 0; j < mat.vexnums; ++j)
{
if (!visited[j] && minnum + mat.matrix[k][j] < pathmin[j])
{
pathmin[j] = minnum + mat.matrix[k][j];
vis[j] = val; //记录上一个节点
}
}
}
//输出最短路径
cout << "从" << u+1 << "到" << v+1 << "的最短路径长度为:" << pathmin[v] << "\n路径为:";
vector<int> path;
while (vis[v] != -1)
{
path.push_back(v + 1);
v = vis[v];
}
path.push_back(u + 1);
reverse(path.begin(), path.end());
for (int i = 0; i < path.size(); i++)
{
if (i == 0) cout << path[i];
else cout << " -> " << path[i];
}
}
int main()
{
int n, m, u, v; cin >> n >> m >> u >> v; //输入顶点数与边数,和需要求的两顶点的最小距离
mat.vexnums = n;
mat.edgenums = m;
for (int i = 0; i < maxn; ++i)
{
for (int j = 0; j < maxn; ++j)
mat.matrix[i][j] = inf;
}
for (int i = 0; i < m; ++i) //初始化图
{
int x, y, w;
cin >> x >> y >> w;
mat.matrix[x-1][y-1] = w;
mat.matrix[y-1][x-1] = w;
}
Dijkstra(u-1, v-1);
system("pause");
return 0;
}
//样例:
//5 7 1 5
//1 4 2
//2 3 5
//1 2 3
//1 3 7
//3 4 4
//4 5 1
//3 5 6
//从1到5的最短路径长度为:3
// 路径为 : 1 -> 4 -> 5
迪杰斯特拉最小生成树
最新推荐文章于 2023-03-28 21:11:37 发布