个人对dijkstra和prim算法的理解

//
// 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
 * */ 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值