Dijkstra最短路径算法

2 篇文章 0 订阅

Dijkstra算法又称为迪杰斯特拉算法。具体思想是从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径。

如下图所示:图片出处
这里写图片描述

最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。具体实现步骤:

1.将起点A放入集合中,A点的权值为0,因为A->A=0。

2.与起点A相连的所有点的权值设置为A->点的距离,连接不到的设置为无穷。并且找出其中最小权值的B放入集合中(此时A->B必定为最小距离)。

3.与B点相连的所有点的权值设置为B->点的距离,并且找出其中最小权值的C点放入集合中(此时C的权值必定为其最小距离)。

4.重复步骤3,直至所有点加入集合中。便能得到所有点与A点的最短距离。

主要代码:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>

using namespace std;

//邻接矩阵的类型定义

#define MAX 10000000
#define MAX_VERTEX_NUM 20
typedef struct 
{
    string vexs[MAX_VERTEX_NUM];//用一维数组存储顶点信息
    int edges[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//用二维数组存储边信息
    int vexnum, edgenum;//顶点数、边数
} MGraph;

//构造有向网的邻接矩阵
void CreateDN_AM(MGraph &G, int n, int e)
{
    G.edgenum = e;
    G.vexnum = n;
    int i, j, k;
    int weight;
    for (i = 0; i < n; i++)
    {
        cin >> G.vexs[i];//输入顶点信息
        cout << G.vexs[i] << " ";
    }
    cout << endl;

    for (i = 0; i < n; i++)
    {
        for (j = 0; j < n; j++)
        {
            G.edges[i][j] = MAX;//将矩阵初始化为MAX  //表示不连通
        }
    }

    for (k = 0; k < e; k++)
    {
        cin >> i >> j >> weight;
        G.edges[i][j] = weight;
        cout << i << " " << j << " " << weight << endl;
    }

}


//地杰斯特拉算法Dijkstra求解某个顶点到其余顶点的最短路径
void ShortestPath_DJ(MGraph &G, int v)
{
    int i, j, k, min;
    int final[MAX_VERTEX_NUM]; //用来标识顶点是否已确定了最短路径
    int dist[MAX_VERTEX_NUM];  //dist数组用来存储当前找到的v到其他各顶点的最短路径 
    string path[2 * MAX_VERTEX_NUM];

    for (i = 0; i < G.vexnum; i++)
    {
        dist[i] = G.edges[v][i];
        if (dist[i] < MAX)
            path[i] = G.vexs[v] + G.vexs[i];  //如果v到i有边的话,把顶点字符存到path字符数组中,表示路径  
        else
            path[i] = " ";
        final[i] = 0;//初始化标识数组为0
    }
    dist[v] = 0;
    final[v] = 1;
    for (j = 1; j < G.vexnum; j++)
    {
        min = MAX;
        for (i = 0; i < G.vexnum; i++)
        {
            if (dist[i] < min && final[i] == 0)
            {
                min = dist[i];
                k = i;
            }
        }//找到dist数组中最小的位置k
        cout << path[k] << " " << dist[k] << endl;//输出最短路径
        final[k] = 1;//设置标志位
        for (i = 0; i < G.vexnum; i++)
        {//遍历每个顶点i和当前的已求出的最短路径的顶点k作比较,若从源点经过顶点K到
            //顶点i的路径,比dist[i]小,则更新顶点dist[i]
            if (dist[i]>dist[k] + G.edges[k][i] && final[i] == 0)
            {
                dist[i] = dist[k] + G.edges[k][i];
                path[i] = path[k] + G.vexs[i];
            }
        }//从整体上来看就是算出k的邻接点的当前最短路径  
    }

}



int main()
{
    freopen("D:\\in.txt", "r",stdin);
    MGraph G;
    CreateDN_AM(G, 6, 18);
    ShortestPath_DJ(G, 6);
    fclose(stdin);//关闭文件 
    //system("pause");
    system("pasue");
    return 0;
}

参考文献:
[1].https://blog.csdn.net/jerry81333/article/details/54772709
[2].https://blog.csdn.net/hackerain/article/details/6055925
[3].https://baike.baidu.com/item/%E6%9C%80%E7%9F%AD%E8%B7%AF%E5%BE%84%E7%AE%97%E6%B3%95/20868554?fr=aladdin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值