伪代码描述思路:
存储结构:dist[ ] / path[ ] /vist[ ]
1、初始化-> dist[ i ]=dege[v] [i] / path[ ]=**/vist[ ] = 0
2、从源点出发(初始化minA=INF),将没加入集合的每一个点的距离与minA进行比较,vist[j]==0 && dist[j]小于minA 则minA=dist[j], 最后得出minA,u=j(赋值操作) 然后vist[u]=1;
3、然后将 u 点加入集合,遍历其余的点,if(dist[u]+edge[u][j] < dist[j])
则 dist[j] = dist[u]+edge[u][j]; 路径加入!
#include<bits/stdc++.h>
#include<stdio.h>
#include <cstring>
#include <stack>
using namespace std;
#define ll long long
#define MAX 100
#define INF 0x3f3f3f3f
int dist[MAX], path[MAX];
struct MGraph{
int edge[MAX][MAX]; //存放顶点之间的权值
int n,e; //顶点数和边数
}G;
void init(){
memset(G.edge,INF,sizeof(G.edge)); //初始化为无穷大
}
void insert(int u,int v, int w)
{
G.edge[u][v]=w; //upadte
}
void printfPath(int path[],int a){
stack<int> s;
//这个循环以由叶子结点到根结点的顺序将其入栈
while(path[a] != -1){
s.push(a);
a = path[a];
}
s.push(a);
while(!s.empty()){
cout << s.top() << " ";//打印栈顶元素,实现了顶点的逆序打印
s.pop();
}
cout << endl;
}
void Dijkstra(MGraph g, int v, int dist[], int path[]){ //顶点默认从0到n
int set[MAX],minA,i,j,u;
//初始化
for(i=0;i<g.n;i++){
dist[i]=g.edge[v][i];
set[i]=0;
if(g.edge[v][i]<INF){
path[i]=v;
}else{
path[i]=-1;
}
}
set[v] = 1;
path[v] = -1;
//初始化结束
for(int i=0;i<g.n-1;i++){
minA=INF; //目前最小的点
//查找剩下顶点最短的点
for(j=0;j<g.n;j++){
if(set[j]==0&&dist[j]<minA){
minA=dist[j];
//set[j]=1; 错误的原因在于 并不一定更新就是最终访问,访问的最终是最小的点
u=j;
}
}
set[u]=1;//次处为最小的点,加入集合中去
for(j=0;j<g.n; j++){
if(set[j]==0&&dist[j]>dist[u]+g.edge[u][j]){
dist[j]=dist[u]+g.edge[u][j];
path[j]=u;//更新路径
}
}
}
}
int main(){
init();
int n, m;//n个点,m条边
int a, x, y, w;
cin >> m >> n;
G.e = m;
G.n = n;
for(int i = 0; i < m; i++){
cin >> x >> y >> w;
insert(x, y, w);
}
Dijkstra(G, 0, dist, path);
printfPath(path, 5);
for(int i = 0; i < n; i++) {
cout << dist[i] << " ";
}
return 0;
}