关于图中的Dijkstra算法(邻接矩阵版)
最近在学习图论,感觉也没有那么难…以前总觉得很难…
//
// main.cpp
// Dijkstra ——不断从dis中选取最小的值,取这个节点(该节点未曾被访问),更新dis,再从dis中找最小值,如此反复
// 邻接矩阵版本
// Created on 2020/10/25.
//
#include <iostream>
using namespace std ;
#include <stack>
const int INFINITY = 65535;//定义不可达
const int Max_Size = 100 ;
int n ,e ,starts ;//顶点个数,边数,初始点
int G[Max_Size][Max_Size];//图
int Visited[Max_Size];//标记是否到达过
int dist[Max_Size];//距离(相对初始点而言——starts)
int path[Max_Size];//路径,每次随距离一起更新
void Create(){//建立图
cin >> n >> e >> starts;
for(int i = 0 ;i<n ;i++ ){//初始化
for(int j = 0 ;j<n ;j++){
if(i == j ){
G[i][j] = 0 ;
}else {
G[i][j] = INFINITY;
}
}
}
for(int i = 0 ;i<e ;i++ ){//插入边
int v1, v2 ,w ;//w是权值
cin >> v1 >> v2 >> w;
G[v1][v2] = w ;
G[v2][v1] = w ;
}
}
void Dijkstra(){//每次对一个顶点操作更新
fill(dist, dist+Max_Size, INFINITY);//将数组dis全部初始化为INFINITY(记为不可达)
memset(Visited, 0, sizeof(Visited));
dist[starts] = 0 ;//保证第一次找到的肯定是starts
for(int i = 0 ;i<n;i++ ){//因为每次都是从未访问的节点中选取一个,然后有n个节点
int u = -1 , min = INFINITY;
for(int j = 0 ;j< n ;j++ ){
if(Visited[j] == 0 && dist[j] < min){//在dis中,找最小的,同时保证未访问
u = j ;
min = dist[j] ;
}
}
if(u == -1) return ;//未找到(表明starts点与其他点不连通)
Visited[u] = 1 ;
for(int j = 0 ;j<n;j++){//找到点之后,更新dis
if(Visited[j] == 0 && G[u][j]!= INFINITY && dist[j] > dist[u] + G[u][j]){//原则:未访问,可达,距离更小
dist[j] =dist[u] + G[u][j];
path[j] = u;
}
}
}
cout <<"到各个顶点最短距离为:";
for(int i = 0 ;i < n; i++){
cout << dist[i]<< " " ;
}
cout << endl ;
}
void path_way(int i ){
stack<int >s ;
cout << "到达5的最短路径是:";
s.push(i);
while (i != 0){
s.push(path[i]);
i = path[i];
}
while(!s.empty()){
cout << s.top()<< " ";
s.pop();
}
cout << endl ;
}
int main() {
Create();
Dijkstra();
path_way(5);
return 0;
}
欢迎指出错误~