//
// Created by Ravanla on 2021/3/3.
//https://blog.csdn.net/m0_45688966/article/details/106040335?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161475436316780266276621%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=161475436316780266276621&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-1-106040335.pc_search_result_hbase_insert&utm_term=dijkstra%E7%AE%97%E6%B3%95+c
//https://www.bilibili.com/video/BV1q4411M7r9
//
//
//
//
//
#include <stdio.h>
#define INF 10000000
#define MaxSize 50
int graph[MaxSize][MaxSize]; //MaxSize为最大顶点数
int dis[MaxSize]; //dis[i]为源点到顶点i的最短距离
int visit[MaxSize]; //visit[i]标记顶点i的最短路径是否已求出visit[i] == 1表示已求出
int prevetrix[MaxSize]; //前驱动点
void dij(int n) {
int count = 0; //count是已求出最短路径的顶点数目
visit[0] = 1;
prevetrix[0] = 0;
count++;
for (int i = 1; i < n; i++) { //初始化
dis[i] = graph[0][i];
prevetrix[i] = 0;
}
while (count < n) {
int min = INF, middle;
for (int i = 1; i < n; i++) {
if (visit[i] == 0 && min > dis[i]) {//找到距离源点最短的顶点middle
min = dis[i];
middle = i;
}
}
visit[middle] = 1;
count++;
for (int final = 1; final < n; final++) {
if (visit[final] == 0 && dis[middle] + graph[middle][final] < dis[final]) {//更新
dis[final] = dis[middle] + graph[middle][final];
prevetrix[final] = middle;//记录final点是由哪来的
}
}
/* prim的代码片段 这里是指
for (int i = 1; i <= points; i++) {//选择出的顶点再延伸更新1号顶点到其它顶点的距离
if (flag[i] == 0 && dis[i] > edge[j][i]) {
dis[i] = edge[j][i];//如果满足条件则更新
}
}
* */
}
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
int a, b, w, path[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
graph[i][j] = INF;
}
}
for (int i = 0; i < m; i++) {
scanf("%d %d %d", &a, &b, &w);
graph[a][b] = w;
}
dij(n);
printf("\n\n");
for (int i = 1; i < n; i++) {
if (dis[i] == INF) {
printf("顶点0到顶点%d没有最短路径\n", i);
} else {
printf("顶点0到顶点%d有长为%d的最短路径:", i, dis[i]);
int cur = i, index = 0;
path[index] = cur;
while (1) {
path[index + 1] = prevetrix[path[index]];
if (path[index + 1] == 0)//等于原点了
break;
index++;//索引下一个点了
}
for (int j = index + 1; j > 0; j--) {
printf("%d->", path[j]);
}
printf("%d\n", path[0]);
}
}
for(int i = 0; i < n; i++){
printf("%d ", prevetrix[i]);
}
}
/*
输入:
6 8
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 5 60
4 3 20
输出:
顶点0到顶点1没有最短路径
顶点0到顶点2有长为10的最短路径:0->2
顶点0到顶点3有长为50的最短路径:0->4->3
顶点0到顶点4有长为30的最短路径:0->4
顶点0到顶点5有长为60的最短路径:0->4->3->5
0 0 0 4 0 3
* */