Dijkstra最短路算法

本文详细介绍了一种用于寻找图中两点间最短路径的经典算法——Dijkstra算法。文章首先介绍了算法的基本概念及其应用场景,并逐步展示了算法的具体步骤,包括如何确定当前点、如何更新其他节点的距离等。此外还提供了一个完整的C++代码示例。

简介

Dijkstra算法,是一种最短路算法。本算法用来求指定一个点到其余各个顶点的最短路径,也叫单源最短路径。

步骤

下面我们就来求一下以1号点为源点,求1号点到其他点的最短路径。
这里写图片描述
首先,我们用e数组表示各边的关系,如下是初始状态。
这里写图片描述
我们开一个dis数组来存储1号点到各点的最短距离。
这里写图片描述
现在我们来找与1点距离最近的点,用这个点来继续更新其他点的最短距离。
容易发现,3号点是与点1距离最近的点。
这里写图片描述
这个时候,我们就可以确定3号点最终的最短距离了。为什么?因为没有点与1点距离比3号点更近,所以3号点的最短距离不可能通过第三个点作为中转站更新。
接下来,我们看看3号点能够更新哪些点。
我们发现3号点连着2,4,5号点,如果能够更新2号点的最短距离,那么当且仅当dis[3]+e[3][2]< dis[2]。其他点一样。
dis[3]+e[3][2] 的确< dis[2],所以dis[2]更新为4,其他同理。
这里写图片描述
继续重新操作,除3号点外,离1最近的是4,5号点(随便选一个吧,选点4),然后再通过点4来更新其他与点4有连接的点.
最后,dis数组为:
这里写图片描述
这个数组即为答案。

实现方法

我们设一个布尔类型的bj数组,表示这个点的最短距离是不是已经为定值。
1.然后我们再选一个点1距离最近的点,记下它为x。
2.然后再用点x更新其他的点。

代码

C++代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,a,b) for (i=a;i<=b;i++) 
#define maxlongint 2139062143
using namespace std;
int bj[2001],dis[2001],e[2001][2001],i,j,u,v,n,m,t,MIN,x,y,z;
int main()
{
    scanf("%d%d",&n,&m);
    fo(i,1,n) 
        fo(j,1,n)
            if (i==j) e[i][j]=0; else e[i][j]=maxlongint;
    fo(i,1,m)
    {
        scanf("%d%d%d",&x,&y,&z);
        e[x][y]=z;
    }
    fo(i,1,n) dis[i]=e[1][i];
    fo(i,1,n) bj[i]=0;
    bj[i]=1;
    fo(i,1,n-1)
    {
        MIN=maxlongint;
        fo(j,1,n)
            if (bj[j]==0 && dis[j]<MIN)
            {
                MIN=dis[j];
                u=j;
            }
        bj[u]=1;
        fo(v,1,n)
            if (e[u][v]<maxlongint) 
                if (dis[u]+e[u][v]<dis[v]) dis[v]=dis[u]+e[u][v];
    }
    fo(i,1,n) printf("%d ",dis[i]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值