图论之最短路问题(acwing模板篇)

目录

朴素的Dijkstra算法:

Dijkstra模板:

 例题:Dijkstra求最短路

堆优化的dijkstra算法

例题:Dijkstra求最短路Ⅱ

Bellman-Ford算法(处理有负权边的图)

 例题:有边数限制的最短路

spfa算法(Bellman-Ford算法的队列优化算法)

spfa求负环

Floyd算法(多源最短路)


名词解释:n:通常代表点数                         m:通常代表边数

源:起点                   单源:一个起点                   多源:多个起点

汇点:终点

入度:有多少条边指向我

出度:以这个点为起点出去的边数

边权:离散数学或数据结构中,图的每条边上带的一个数值,他代表的含义可以是长度等等,这个值就是边权

框架图:

朴素的Dijkstra算法:

由于它的时间复杂度是O(N^2)边数与时间复杂度无关,所以它适合做稠密图

稠密图:边数是点数的2~3倍

ACwing算法基础课全程笔记(2021年8月12日开始重写+优化)_hebtu_Kangweiqi的博客-CSDN博客_acwing笔记算法基础课笔记,请支持正版https://blog.csdn.net/hebtu_Kangweiqi/article/details/109124329借用大佬的图= =

Dijkstra模板:

98504cdcddd6d683a91c09357395d12.png

 例题:Dijkstra求最短路

给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。

请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1

 思路解析:有贪心的感觉,每次我都选择离我距离最小的那条走,然后最1~j的最短距离就变成

1~t点的距离 t~j的最短距离

 建议自己看着代码自己在图上模拟一下,会感受到这个算法之妙!!!

#include<iostream>
using namespace std;
const int N = 510;
int n, m;
int g[N][N];//采用邻接矩阵存储
int dist[N];//距离数组
bool st[N];//判断数组
int dijkstra() 
{
    memset(dist, 0x3f, sizeof dist);//初始化数组的值为一个很大的数1e9
    dist[1] = 0;//将第1号点的到自身的距离初始化为0
    for (int i = 0; i < n; i++) 
    {//n次迭代
        int t = -1;//随便的一个没有意义的数即可:目的是下面的寻找出2~n内距离点1最小的数
        for (int j = 1; j <= n; j++)//从1开始遍历:注意这个细节
        {
            if (!st[j] && (t == -1 || dist[j] < dist[t]))//如果该点未被走过
            {
                t = j;//相当于寻找最小值  1~1  1~2
            }
        }
        st[t] = 1;//标记已经用过了这个点
        for (int j = 1; j <= n; j++)//遍历1号点到n号点
        {//更新距离
            dist[j] = min(dist[j], dist[t] + g[t][j]);//1~j点的距离变为了:1~t的距离+t~j的距离
        }
    }
    if (dist[n] == 0x3f3f3
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值