首页 > 编程语言 >图论最短路算法笔记

图论最短路算法笔记

时间:2024-11-24 12:14:32浏览次数:5  
标签:图论 int 短路 head 算法 EDGE MAXN dis

1 图的基本操作

1.1 图的存储

图存储有两种方法:邻接表邻接矩阵

  • 邻接表
g[N][N] = {};
...
memset(g, 0x3f, sizeof g);
g[u][v] = w;
  • 邻接矩阵
int head[N] = {};
memset(head, 0x3f, sizeof head); 
struct edge{
    int pre, to, val;
}EDGE[N];
inline void addedge(int u, int v, int w, int i){
    EDGE[i] = {v, w, head[u]};
    head[u] = i;
}

1.2 图的遍历

图的遍历是指从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次(访问一次,但不止用到一次)。 图的遍历操作和树的遍历操作功能相似。

2 最短路算法

图求最短路有算法:

  • Floyd
  • Dijkstra
  • SPFA(死了)
  • Bellman-Ford
  • ...

2.1 Floyd

  • 用途:求任意两个结点之间的最短路
  • 复杂度:\(O(n^3)\)
  • 适用:适用于任何图,不管有向无向,边权正负,但是最短路必须存在
for(reg int k=1; k<=n; ++k)
    for(reg int i=1; i<=n; ++i)
        for(reg int j=1; j<=n; ++j)
            if(g[i][k] + g[k][j] < g[i][j])
                g[i][j] = g[i][k]+g[k][j];

以上:g 为邻接矩阵。

2.2 Dijkstra

  • 用途:单源最短路径
  • 复杂度:\(O(n^2)\) -> \(O(nlogn)\)
  • 适用:非负权图

步骤

  • 1 初始化:
    源点 \(u\),dis[N]book[N]
    建立集合 \(S\) 与 \(V-S\)。刚开始,只有 \(u\) 在 \(S\) 中。
vector<edge> e[MAXN];
int dis[MAXN], book[MAXN];

image

  • 2 找 dis[] 最小:
    开始,dis[n] 为 源点 \(u \rightarrow n\) 的特殊最短路。
    寻找 dis[n] 中最小的节点 \(t\)(可优化)。
    image
    image
  • 3 加入集合 \(S\)
    加入集合 \(S\),现在 \(S\) 表示为最短路的部分。
    image
  • 4 借东风
    与 Floyd 较为类似,就是以一个节点 \(i\) 作中转点,看看能不能将与周围的节点 \(k_1, k_2, ..., k_n\) 的边 \(k_1 \rightarrow i \rightarrow k_2\) 的长度减小(松弛)。
    image
  • 5 判结束
    如果 \(V-S\) 集合为空集,那么全部的 dis[] 都处理完毕,这时的 dis[n] 为 源点 \(u \rightarrow n\) 的最短路。
    image

朴素算法(没写过,来自 oi-wiki):

struct edge {
    int v, w;
};
vector<edge> e[MAXN];
int dis[MAXN], vis[MAXN];
void dijkstra(int n, int s) {
    memset(dis, 0x3f, (n + 1) * sizeof(int));
    dis[s] = 0;
    for (int i = 1; i <= n; i++) {
        int u = 0, mind = 0x3f3f3f3f;
        for (int j = 1; j <= n; j++)
            if (!vis[j] && dis[j] < mind)
                u = j, mind = dis[j];
        vis[u] = true;
        for (auto ed : e[u]) {
            int v = ed.v, w = ed.w;
            if (dis[v] > dis[u] + w) 
                dis[v] = dis[u] + w;
        }
    }
}

堆优化

堆优化就是用堆进行优化,而朴素的算法是“扫描”一遍图找最小的点。而小根堆优先队列优化就可以快速维护最小的点,大大减少时间复杂度( \(O(nlogn)\) )。

struct edge {
    int pre, to, val;
}EDGE[MAXN];
int dis[MAXN], book[MAXN], head[MAXN];

inline void addedge(int u, int v, int w, int i){
    EDGE[i] = {v, w, head[u]};
    head[u] = i;
}

inline void dijkstra(int s){
    memset(dis, inf, sizeof dis);
    priority_queue <pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > heap;
    heap.push({0, s});
    while(!heap.empty()){
        int t = heap.top().second;
        heap.pop();
        if(book[t])
            continue;
        book[t] = true;
        for(reg int i=head[t]; i; i=EDGE[i].pre){
            if(dis[EDGE[i].to] > EDGE[i].val+dis[t]){
                dis[EDGE[i].to] = EDGE[i].to+dis[t];
                heap.push({dis[EDGE[i].to], EDGE[i].to});
            }
        }
    }
    return;
}

标签:图论,int,短路,head,算法,EDGE,MAXN,dis
From: https://www.cnblogs.com/redlightFancy/p/18565616

相关文章

  • 字节 NLP 算法岗一面面试题7道(含解析)
    最近这一两周不少互联网公司都已经开始秋招提前批面试了。不同以往的是,当前职场环境已不再是那个双向奔赴时代了。求职者在变多,HC在变少,岗位要求还更高了。最近,我们又陆续整理了很多大厂的面试题,帮助一些球友解惑答疑,分享技术面试中的那些弯弯绕绕。总结如下:《大模型面......
  • 【数据集】【YOLO】【目标检测】牛只识别数据集 3371 张,YOLO牛只识别算法实战训练教程
     一、数据集介绍【数据集】牛只识别数据集3371张,目标检测,包含YOLO/VOC格式标注。数据集中包含1种分类:names:['cattle'],表示"牛"。数据集来自国内外网站图片采集、无人机采集、监控视频采集数据,含三种视角!!如下所示;可用于无人机牛只识别,监控牛只识别。检测场景为牧场、......
  • 用python写一段k-means聚类算法,要求使其能够显示聚类前后的差异,绘图使其可视化
    当您使用K-means算法时,可以使用scikit-learn库中的KMeans类来实现。以下是一个示例代码,可以帮助您理解如何使用K-means算法进行聚类,并使用matplotlib库绘制可视化结果。importnumpyasnpfromsklearn.clusterimportKMeansimportmatplotlib.pyplotasplt#创建一个......
  • C++,Java,Python,Javascript实现二分查找算法
    二分查找算法是一种在有序数组中查找特定元素的搜索算法。它的基本思想是将数组分成两半,通过比较中间元素与目标值来决定是在左半部分还是右半部分继续查找,从而逐步缩小查找范围直到找到目标值或者确定目标值不存在于数组中。下面是使用C++、Java、Python和JavaScript实现二......
  • Floyd算法计算最短距离
     importcom.google.common.collect.HashBasedTable;importcom.google.common.collect.Table;importjava.util.Arrays;publicclassApp{//正无穷publicstaticdoubleinfinity=Double.POSITIVE_INFINITY;/***计算所有节点最短路径的Floyd......
  • 《链表算法:浅谈并实现一下链表各种排序算法及其性能》
    前置知识数据结构-链表数组排序算法:选择排序[解法1],归并排序递归版[解法2],归并排序迭代法[解法3最优解][归并部分基础]合并两个有序链表如果您不满足于此,笔者也提供冒泡排序,插入排序,快速排序的链表写法。以及,我们会在下文讨论为什么不说明希尔排序,堆排序,因为两者不适合......
  • 多种智能优化算法优化极致梯度提升算法(XGBoost)的数据回归预测
    极致梯度提升算法(XGBoost)是一种非常高效的梯度提升框架,广泛应用于监督学习任务,特别是在数据回归预测中。尽管XGBoost通过自动调节参数和剪枝等技术已经具有很强的性能,但通过多种智能优化算法进一步优化其参数,可以显著提升其在数据回归预测任务中的表现。代码原理及流程1.XGBo......
  • 4- 机器学习原理与实践——聚类分析(k均值算法)
      k均值(k-means)算法是一种最老的、最广泛使用的聚类算法。该算法之所以称为k均值,那是因为它可以发现k个不同的簇,且每个簇的中心均采用簇中所含数据点的均值计算而成。1算法描述  在k均值算法中,质心是定义聚类原型(也就是机器学习获得的结果)的核心。除了第一次......
  • 改进的 A算法的路径规划(路径规划+代码+毕业设计)
    现推出专栏项目:从图像处理(去雾/去雨)/目标检测/目标跟踪/单目测距/到人体姿态识别等视觉感知项目--------------------更多视觉和自动驾驶项目请见下面链接---------------------------:YOLOv8界面-目标检测+语义分割+追踪+姿态识别(姿态估计)+界面DeepSort/ByteTrack-PyQt-GU......
  • 算法笔试面试2
    用两个栈来模拟实现队列publicclassMyQueue{privatestaticStack<Integer>inStack;privatestaticStack<Integer>outStack;publicMyQueue(){inStack=newStack<>();outStack=newStack<>();}//像队列中......