Djkstra解决最短路问题

一.原理介绍:

首先把起点距离最近的点存下来,然后进行松弛(即找到距离起点最短的那个点),然后对之后的点重复此类操作,直到找到终点即可。下面我用图来演示一遍:

 注:(d数组表示到某个点的距离)

首先,d[1]=0,因为起点到起点的距离为0,然后起点衍生的两个点为 2  和  31到2距离为1,所以d[2]=1,同理,d[3]=1,之后,2  和  3  均衍生了2个点,因此,d[4]=d[2]+2,d[5]=d[2]+2,  d[6]=d[3]+3,   d[7]=d[3]+3;之后到终点了,这里有些不同,因为到8的点有4个,我们需要一个一个进行比较,算出最近的点,通过计算,我们得出最近的点为  4,因为d[4]=3,d[8]=d[4]+1  d[8]=4,所以到8的最短路为四。

 二:题目展示:

三:代码展示:

#include<bits/stdc++.h>
using namespace std;
const int N= 510;
int g[N][N],d[N];//g数组存的是点与点的距离,d则是到某点的距离。
bool str[N];
int n,m;
int dijkstra()
{
    memset(d,0x3f,sizeof d);//初始化d为无穷大。
    d[1]=0;//起点的距离
    for(int i=0;i<n;i++)
    {
        int t=-1;
        for(int j=1;j<=n;j++)
        {
            if(!str[j]&&(t==-1||d[t]>d[j]))//寻找最短的2个点。
            t=j;
            if(t==n)break;
        }
        str[t]=true;
        for(int i=1;i<=n;i++)
        {
            d[i]=min(d[i],d[t]+g[t][i]);//比较到某点的路径,看哪条最短。
        }
    }
    if(d[n]==0x3f3f3f3f)return -1;//如果到不了第n点,那么d[n]=无穷,返回-1
    return d[n];
}
int main()
{
    cin>>n>>m;
    memset(g,0x3f,sizeof g);//同d数组的操作
    while(m--)
    {
        int a,b,c;
        cin>>a>>b>>c;
        g[a][b]=min(g[a][b],c);//a到b的距离为c。
    }
    cout<<dijkstra()<<endl;
}

四:总结: 

 在提一嘴,如果有多条路到某一点,那么保留最短的那一条便可以了,因为,到终点的距离都是所以最短路组成的。另外,这个算法不能算带有负权边的最短路,可能会算错,因为dijksta更新时是更新未更新的点,已更新点到其他点的距离不会再进行更新了,导致有负数的那条边不会保留,而是会跳过。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值