#include<iostream>
#include<limits.h>
#include<algorithm>
#include<string>
#include<vector>
#include<map>
#define INSERT_EDGE(v,w,weight) am[v][w] = am[w][v] = weight
using namespace std;
int am[16][16];
int node;
int u;
string inf[16][16];
vector<int>vec;
int s[16];
bool s_bool[16];
int dist[16];
int dist_h[16];
int dist_sort[16];
int prevx[16];
void Dijkstra(int n, int dist[], int prevx[], int am[16][16]);
void get_path(int n);
int main() {
cout << "输入节点个数:";
cin>>node;
INSERT_EDGE(1, 2, 1);
INSERT_EDGE(2, 3, 2);
INSERT_EDGE(2, 7, 3);
INSERT_EDGE(3, 7, 2);
INSERT_EDGE(3, 6, 7);
INSERT_EDGE(6, 4, 3);
INSERT_EDGE(7, 4, 6);
INSERT_EDGE(4, 8, 4);
INSERT_EDGE(7, 5, 11);
INSERT_EDGE(5, 8, 9);
cout << "输入邻接矩阵(用0表示无路劲,把它看作无穷大):"<<endl;
for (int i = 1;i <= node;i++) {
for (int j = 1;j <= node;j++) {
if (am[i][j]==0) {
am[i][j] = INT_MAX;
inf[i][j] = "无";
}
}
}
cout << endl << endl;
for (int i = 1;i <= node;i++) {
for (int j = 1;j <= node;j++) {
if (am[i][j]!=INT_MAX) {
cout << am[i][j]<<"\t";
}
else {
cout << inf[i][j]<<"\t";
}
}
cout << endl;
}
cout << endl << endl << endl << endl;
Dijkstra(node, dist, prevx, am);
cout << "最短路径是:" << " ";
cout << dist[node];
cout << endl;
vec.push_back(node);
get_path(node);
cout << "路径走法是:";
for (int i = (int)vec.size() - 1;i >= 0;i--) {
cout << vec[i];
if (i!=0) {
cout << " -> ";
}
}
cout << endl << endl;
}
void Dijkstra(int n, int dist[], int prevx[], int am[16][16]) {
for (int i = 1;i <= n;i++) {
s_bool[i] = false;
}
s_bool[1] = true;
int d = 1;
s[d] = 1;
for (int i = 1;i <= n;i++) {
dist[i] = am[1][i];
}
for (int k = 1;k < n;k++) {
//选出最小的权值,dist_sort是对没有加入s集合的元素进行排序
int c = 1;
for (int i = 1;i <= n;i++) {
//当u==7时,dist[6]==10,dist[4]==10,dist[5]==15
if (s_bool[i] == false) {
dist_h[i] = dist[i];
dist_sort[c] = dist[i];
c++;
}
}
sort(dist_sort + 1, dist_sort + c);
//当u==7时,dist_sort里面有10,10,15,因为有两个都是10,所有会导致循环2次,导致u无法等于4,直接跳过4,等于6,所以必须要用break终止循环
for (int i = 1;i <= n;i++) {
if (dist_sort[1] == dist_h[i] && s_bool[i] == false) {
cout<<"dist_sort[1]的最小取值:::::"<<dist_sort[1]<<endl;
dist[i] = dist_h[i];
d++;
s[d] = i;
u = i;
s_bool[u] = true;
break;
}
}
for (int j = 1;j <= n;j++) {
if ((s_bool[j] == false) && (am[u][j]<INT_MAX)) {
int newdist = dist[u] + am[u][j];
if (newdist<dist[j]) {
//当u==7时,求出dist[4]==10和dist[5]==15
dist[j] = newdist;
prevx[j] = u;
}
}
}
}
//因为u不能为1,所以prevx没有被赋值的那个的值一定是1
for (int i = 2;i <= n;i++) {
if (prevx[i]==0) {
prevx[i] = 1;
}
}
for(int i=1;i<=node;i++){
cout<<"prevx["<<i<<"]="<<prevx[i]<<endl;
}
for(int i=1;i<=node;i++){
cout<<"s["<<i<<"]="<<s[i]<<endl;
}
}
void get_path(int n) {
if(n!=1) {
vec.push_back(prevx[n]);
get_path(prevx[n]);
}
}
输入节点个数:8
输入邻接矩阵(用0表示无路劲,把它看作无穷大):
无 1 无 无 无 无 无 无
1 无 2 无 无 无 3 无
无 2 无 无 无 7 2 无
无 无 无 无 无 3 6 4
无 无 无 无 无 无 11 9
无 无 7 3 无 无 无 无
无 3 2 6 11 无 无 无
无 无 无 4 9 无 无 无
dist_sort[1]的最小取值:::::1
dist_sort[1]的最小取值:::::3
dist_sort[1]的最小取值:::::4
dist_sort[1]的最小取值:::::10
dist_sort[1]的最小取值:::::10
dist_sort[1]的最小取值:::::14
dist_sort[1]的最小取值:::::15
prevx[1]=0
prevx[2]=1
prevx[3]=2
prevx[4]=7
prevx[5]=7
prevx[6]=3
prevx[7]=2
prevx[8]=4
s[1]=1
s[2]=2
s[3]=3
s[4]=7
s[5]=4
s[6]=6
s[7]=8
s[8]=5
最短路径是: 14
路径走法是:1 -> 2 -> 7 -> 4 -> 8
Program ended with exit code: 0