Djikstra最短路径算法

7 篇文章 0 订阅
3 篇文章 0 订阅

      一、概括:贪心策略

Dijktra最短路径算法采用的是一种贪心的策略,通过逐次地找到各点距起点的最短路径并由该路径更新该顶点出度的路径,进而使图中所有点距离起点路径最短的算法。

   详细推导过程可见:https://blog.csdn.net/qq_35644234/article/details/60870719

      二、数据结构:

1.一维数组:

int dist[] :用于保存距离起点最短路径,若与起点不连通则用一个较大的数表示(如16进制的:0x3f3f3f)

int/bool flag[]:用于保存已经得出最短路径的顶点的集合,已得出则为1/true,否则为0/false

 char s[] :用于保存图中的顶点名称等,也可以用一个结构体保存。

2.二维数组:

int map[][]:邻接矩阵(二维数组)的形式保存一个图的基本信息,其中权重为初始路径。

三、代码实现:

输入:

总顶点数:n     总边数:m

接下来m 行: 顶点:a 顶点:b 距离:len

输入起点:start

输出:

各顶点据起点的最短距离

dist [ i ]

c/c++混搭语言代码:

注释:输入数据均以1为起点,秉承勤俭节约的中华传统,数组都是以0为起点(其实就是懒得改了)

测试数据:

图片来源:https://blog.csdn.net/qq_35644234/article/details/60870719

6 8
1 3 10
1 5 30
1 6 100
2 3 5
3 4 50
4 6 10
5 4 20
5 6 60
1

输出:

1 ->1 : 4144959
1 ->2 : 4144959  //为一个大数,可在输出时改成其他符号如~
1 ->3 : 10
1 ->4 : 50
1 ->5 : 30
1 ->6 : 60

#include<stdio.h>
#include<string.h>
#define MAX 100
#define inf 0x3f3f3f
#define min(a,b) a<b?a:b

int map[MAX][MAX];
bool flag[MAX];
int dist[MAX];
int n,m;//n是顶点数,m为边数

void find_shortest(int start);

int main()
{
    int a,b,len;//顶点 顶点 距离
    int start;//起点

    memset(map,0,sizeof(int)*MAX*MAX);
    scanf("%d%d",&n,&m);
    while(m--)//获取图信息
    {
        scanf("%d %d %d",&a,&b,&len);
        map[a-1][b-1] = len;//数组以0开始,为方便输入数据以1开始
    }
    for(int i = 0 ; i<n ; i++)
        for(int j = 0 ; j<n ; j++)
            if(map[i][j]==0)
                map[i][j] = inf;

    scanf("%d",&start);//输入起点
    find_shortest(start-1);//方便输入数据,start-1
    for(int i = 0 ; i<n ; i++)
      printf("%d ->%d : %d\n",start,i+1,dist[i]);//方便观察数据i+1.

    return 0;
}

void find_shortest(int start)
{

for(int i = 0 ; i<n ; i++)
    {
        flag[i] = false;
        dist[i] = inf;
    }
    flag[0] = true;
    dist[0] = 0;//初始化集合和最短路径

    for(int i = 0 ; i<n ; i++)
        dist[i] = map[start][i];//将起点各出度赋给最短路径数组

      for(int i = 0 ; i<n ; i++)//保证所有与起点连通的顶点都加入集合
      {
          int min = inf;//保存起点到顶点的距离
          int t = start;//保存顶点

           for(int j = 0 ; j<n ; j++)//打擂台找集合外距起点最短距离
           {
               if(!flag[j]&&dist[j]<min)
               {
                   min = dist[j];//记录最短距离
                   t = j;//记录顶点
               }
           }

           if(t == start)
            return ;//没有与起点连通的顶点

            flag[t] = true;//将该顶点加入集合
          for(int j = 0 ; j<n ; j++)//维护该顶点出度的最短路径
          {
              if(!flag[j]&&map[t][j]<min)//保证不在集合内且与该顶点连通(出度)
                dist[j] = min(dist[j],dist[t]+map[t][j]);
          }
      }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值