dijkstra算法求单源最短路径算法代码coding

dijkstra算法求单源最短路径

我引用了这位大佬的文章:

https://blog.csdn.net/xiaoxi_hahaha/article/details/110257368
但是他的文章代码有一些问题, 我进行了一些修改, 特此进行记录

先贴出原作者源代码:
原作者把每一行的注释都写得很清楚,很感谢

const int inf = 500;  //可以给别的值,只要大于图中任何一边的距离即可
vector<int> dijkstra(vector<vector<int> > G,int source)
{
    int n = G.size(); //n代表图的顶点个数
    vector<int> dis(n,inf); //dis代表源点到其它点的最短距离,inf代表无穷,初始化vector
    vector<int> vis(n,false); //vis代表某个顶点是否被访问过,初始化所有的顶点为false
    //源点到源点的距离为0
    dis[source]=0;
    
    /*
        根据前面咱们的分析可以知道,要不断寻找没有被访问过且距离源点最近的点,有n个顶点,
        就要寻找n-1次,找到点之后,对其邻接点进行松弛,为什么只要寻找n-1个点呢?因为当
        剩下一个点的时候,这个点已经没有需要松弛的邻接点了。此时从源点到这个点的距离就是最短距离了。
    */
    //可以使用一个for循环,循环n-1次,来寻找n-1个点
    for(int i=0; i<n-1; i++)
    {
        int node = -1;  //进入循环之后,假设一开始不知道哪个是没有被访问过且距离源点最短的点
        for(int j=0;j<n;j++)  //使用这个循环开始寻找没有被访问过且距离源点最短距离的点
        {
            if(!vis[j] && (node == -1 || dis[j]<dis[node]))
            {
                node = j;  //把当前距离源点最短距离的点给node
            }
        }
        //对这个距离源点最短距离的点的所有邻接点进行松弛
        for(int j=0; j<n; j++)
        {
            dis[j]=min(dis[j],dis[node]+G[node][j]);
            /*
                这边要特别注意:对于不是node的邻接点并不会影响它原来的距离,以2点为例
                对于邻接的已经访问过的点也不会产生影响,以3点为例
            */
        }
        //标记为已访问过
        vis[true];
    }
    return dis;
}


我觉得错误点就在于第一个for循环, 并不符合dijsktra算法的要求, 原作者用用节点0到5进行遍历,这不是dijsktra的算法要求, 这里的循环条件应该改为:当ins序列中并不是所有的点都被标记过, 则循环继续, 而且source源点变量也没有发挥它应有的价值,我改进的代码如下:

int sum(vector<int> a)  //用来计算是否每一个点都被标记过, 如果sum值为7说明全部被标记过
{
    int s = 0;
    for(vector<int>::iterator iter = a.begin();iter != a.end();iter++)
        s += *iter;
    return s;
}

vector<int> dijkstra(vector<vector<int>> G,int source)
{
    const int inf = 1e8;
    int n = G.size();
    vector<int> road(n,inf);
    vector<int> ins(n,0);
    road[source] = 0;
    ins[source] = 1;
    while(sum(ins)!=7)
    {
        for(int i=0;i<n;i++)
            road[i] = min(road[i],road[source]+G[source][i]);
        int node = -1;
        for(int i=0;i<n;i++)
            if(!ins[i] && (node==-1 ||road[i]<road[node]))
                node = i;
        source = node;
        ins[source] = 1;
    }
    return road;
}

最后贴上相应的源程序方便大家直接运行看结果:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int inf = 1e8;
int sum(vector<int> a)  //用来计算是否每一个点都被标记过, 如果sum值为7说明全部被标记过
{
    int s = 0;
    for(vector<int>::iterator iter = a.begin();iter != a.end();iter++)
        s += *iter;
    return s;
}

vector<int> dijkstra(vector<vector<int>> G,int source)
{
//    const int inf = 1e8;
    int n = G.size();
    vector<int> road(n,inf);
    vector<int> ins(n,0);
    road[source] = 0;
    ins[source] = 1;
    while(sum(ins)!=7)
    {
        for(int i=0;i<n;i++)
            road[i] = min(road[i],road[source]+G[source][i]);
        int node = -1;
        for(int i=0;i<n;i++)
            if(!ins[i] && (node==-1 ||road[i]<road[node]))
                node = i;
        source = node;
        ins[source] = 1;
    }
    return road;
}
int main()
{
    vector<vector<int>> G = {{0,5,2,inf,inf,inf,inf},{5,0,inf,1,6,inf,inf},{2,inf,0,6,inf,8,inf},{inf,1,6,0,1,2,inf},{inf,6,inf,1,0,inf,7},{inf,inf,8,2,inf,0,3},{inf,inf,inf,inf,7,3,0}};
    vector<int> a = dijkstra(G, 0);
    for(int i=0;i<G.size();i++)
        cout<<a[i]<<endl;
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值