首页 > 编程语言 >用 Dijkstra 算法解决最短路问题

用 Dijkstra 算法解决最短路问题

时间:2023-08-22 10:58:35浏览次数:32  
标签:dist int 短路 源点 Dijkstra 算法 var include 号点

话不多说,先看图

1.1 朴素版的Dijkstra算法

一般用到这个情况稠密图,也就是节点的个数比边的个数少。 (稠密图用邻接矩阵存储)

#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 510;

int n, m;
int g[N][N];//稠密图用邻接矩阵,g[a][b] 表示从a点到b点的距离
int dist[N];//用于存储每个店到起点的最小距离
bool st[N];//用于在更新最短距离时,判断当前点的最短距离是否确定,是否需要更新

int dijkstra(){
    
    memset(dist, 0x3f, sizeof dist);//初始化距离, 0x3f代表无限大
    dist[1] = 0;//第一个点到自身的距离时0
    
    for(int i = 0; i < n; i++){//有n个点需要进行n次迭代
    
        int t = -1;    //t存储当前访问的点
        
        for(int j=1; j<=n; j++)  //这里的 j 代表从1号点开始
            if(!st[j] && (t == -1 || dist[t] > dist[j]))   //寻找未确定最短路径的点钟距离最短的点
                t = j;
        
        for(int j = 1; j<=n; j++)
            dist[j] = min(dist[j], dist[t] + g[t][j]);
            
        st[t] = true;
        
    }
    
    if(dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}

int main(){
    scanf("%d%d", &n, &m);
    
    memset(g, 0x3f, sizeof g);//初始化距离
    
    while(m--){
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        
        g[a][b] = min(g[a][b], c);//和之前a点到b点的最小距离进行比较,取两个中的最小值
    }
    
    printf("%d\n", dijkstra());
    
    return 0;
}

2.2 堆优化版的Dijkstra算法

用到这种情况的是稀疏图。 (点多边的数目少)

思路:

1 号点为例,判断一下1号点到源点的最短距离是不是已经确定了, 如果已经确定了, 跳出本次循环。如果还没有确定,厕把他的 st[1] = true , 这里思考一下我们为什么把1号点的状态改为 true, 因为所有指向1 号点的点最短距离已经确定, 自然 1 号点的最短距离也就确定了, 接下来遍历一下1号点所有指向的点 更新 1 号点指向的点的最短距离 ,

#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>

using namespace std;

typedef pair<int, int> PII;

const int N = 1e6 + 10;

int n, m;
int h[N], w[N], e[N], ne[N], idx;
int dist[N];
bool st[N];

void add(int a, int b, int c)
{
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}

int dijkstra(){
    memset(dist, 0x3f, sizeof dist);  初始化所有点到源点的距离为 无穷大
    dist[1] = 0;  //  1 号点就是源点, 所有到自身的距离是 0
    priority_queue<PII, vector<PII>, greater<PII>> heap; //小根堆
    heap.push({0, 1});  // 距离源点最近的点入堆
    
    while(heap.size()) // 堆不空
    {
        auto t = heap.top();
        heap.pop();
        
        int var = t.second;  //取到 还没有确定到源点的最短距离的点中 到源点距离最近的点
        
        if(st[var]) continue; //判断一下该点到源点的距离是否已经确定, 如果确定跳出本次循环
        st[var] = true;
        
        for(int i = h[var]; i != -1; i = ne[i])//遍历一下var 所有指向的点
        {
            int j = e[i];
            if(dist[j] > dist[var] + w[i])
            {
                dist[j] = dist[var] + w[i];
                heap.push({dist[j], j});
            }
        }
    }
    
    if(dist[n] == 0x3f3f3f3f) return -1;
    return dist[n];
}

int main(){
    scanf("%d%d", &n, &m);
    
    memset(h, -1, sizeof h);
    
    while(m--){
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c);
    }
    
    printf("%d\n", dijkstra());
    
    return 0;
}

标签:dist,int,短路,源点,Dijkstra,算法,var,include,号点
From: https://www.cnblogs.com/tomlove/p/17647953.html

相关文章

  • 【校招VIP】java语言考点之垃圾回收算法
    考点介绍:垃圾回收算法是必考题。GC中的垃圾指的是存在于内存中的、不会再被使用的对象。而垃圾回收就是把那些不再被使用的对象进行清除,收回占用的内存空间......一、考点题目1、java中如何判断对象是否是垃圾?解答:引用计数:在对象中添加一个引用计数器,如果被引用计数器加1,引用......
  • 加密算法分类
    密码加密算法针对密码存储的加密算法通常会使用一些特定的哈希函数或密码学技术,以确保用户密码在存储时是安全的。bcrypt:这是一种基于Blowfish加密算法的密码哈希函数。它适用于存储密码,因为它的加密强度可以根据需要进行调整,以抵御暴力破解和彩虹表等攻击。scrypt:与bc......
  • [Trick] [算法学习笔记] 线段树
    事先声明:本文并非线段树教学。只是一些理解Trick。若您需从0学起线段树建议您移步其他博文呢qwq感谢Idea提供尺子姐姐的博客!,尺子好闪,拜谢尺子!我们在学习线段树的时候,对于乘法“lazytag先乘再加”是不是难以理解?这里介绍一种线段树思考方法。我们可以将序列中的每个元素......
  • 【数据结构】排序 内部排序算法的比较和应用
    1.简单复习一下前面学到的排序算法三种插入排序:直接插入:依次将后面无序序列中头部的元素插入前面的有序序列中(找到插入位置,这个位置后面的元素一律后移)折半插入:相比直接插入只是用折半查找的方式查找插入位置,元素的移动操作不变希尔排序:把相隔一定步长d的元素放入一个子表......
  • 蒙特卡洛算法代码
    蒙特卡洛算法是一个常用的解题方法之一。以下是一个简单的蒙特卡洛求解圆周率π的代码示例:点击查看代码importrandomdefmonte_carlo_pi(n):count=0total=nfor_inrange(n):#在单位正方形内随机生成点的坐标x=random.unifor......
  • 文心一言 VS 讯飞星火 VS chatgpt (79)-- 算法导论7.4 4题
    四、请用go语言,证明:RANDOMIZED-QUICKSORT期望运行时间是Ω(nlgn)。文心一言:首先,为了证明RANDOMIZED-QUICKSORT的期望运行时间是Ω(nlgn),我们需要证明在最坏的情况下,该算法的运行时间是O(nlgn)。然后,我们需要证明在最坏的情况下,算法的期望运行时间是Ω(nlgn)。RANDOMIZED-QUIC......
  • DFA算法实现查找敏感词功能
    publicclassDFAFilter{privateSet<String>sensitiveWords;privateintmaxLength;publicDFAFilter(){sensitiveWords=newHashSet<>();maxLength=0;}publicstaticvoidmain(String[]args){......
  • 代码随想录算法训练营第二十一天| 530.二叉搜索树的最小绝对差 501.二叉搜索树中的
     530.二叉搜索树的最小绝对差   卡哥建议:需要领悟一下二叉树遍历上双指针操作,优先掌握递归   题目链接/文章讲解:https://programmercarl.com/0530.%E4%BA%8C%E5%8F%89%E6%90%9C%E7%B4%A2%E6%A0%91%E7%9A%84%E6%9C%80%E5%B0%8F%E7%BB%9D%E5%AF%B9%E5%B7%AE.html ......
  • 多元分类预测 | Matlab鲸鱼优化算法优化深度极限学习机(WOA-DELM)分类预测
     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......
  • 多元分类预测 | Matlab粒子群优化算法优化深度极限学习机(PSO-DELM)分类预测
     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,matlab项目合作可私信。......