最短路问题的五种算法

图论 ——五种最短路算法 文章目录 前言 一、最短路是什么? 二、朴素Dijkstra算法 三、堆优化版Dijkstra算法 四、Bellman-Ford算法 五、Spfa算法 六、Floyd算法 总结 前言 本篇文章讲的是图论里的最短路问题,如果你还没有图论的基础知识,可以看看我之前的文章: DFS(深度优先算法)BFS(广度优先算法)邻接表和邻接矩阵、树的遍历 (DFS和BFS) 这些都是关于图论的基本知识。 一、最短路是什么? 最短路径: 从某个点A(位置)到另一个点B(位置)的最.. 阅读详情


基础算法合集:
https://blog.youkuaiyun.com/GD_ONE/article/details/104061907

摘要

本文主要介绍关于图的最短路的五种常用算法和其应用。朴素Dijkstra, 堆优化Dijkstra,Bellman-Ford,SPFA, Floyd。这几种算法有各自的优势和劣势,适用于不同的场景。
另:本篇文章篇幅较长,但难度不大, 建议学习算法的同时,自己手动画图,并模拟算法流程,将会一目了然,所见即所得!


单源最短路: 一个点到其他点的最短路。

无负边权时适用算法(所有边长都为正数):

  • 稠密图: 朴素Dijkstra

  • 稀疏图: 堆优化Dijkstra, SPFA

有负边权时适用算法:

  • SPFA
  • Bellman-Ford

求有边数限制的单源最短路:

  • Bellman-Ford

多源汇最短路: 任意两点间的最短路。

  • Floyd

图的存储方式

存储稠密图时,使用邻接矩阵。
存储稀疏图时,使用邻接表。
稠密图是指边数远大于点数,稀疏图是边数和点数差不多相等。
以n表示点数, m表示边数,
一般来说题目数据是n < 100, m < 10000 的图是稠密图, 是n<10000, m<10000的图是稀疏图。


朴素Dijkstra

算法思想:

朴素DijKstra的思想是通过一个距离起点A最近的点B,缩短起点A通过点B到达其他点的距离,因为只有通过距离起点最近的点,才有可能缩短起点到达其他点的距离。
所以一共分两步:
第一步:找到距离起点最近的点。
第二步:通过该点缩短起点到达其他点的距离。

比如:

在这里插入图片描述
对于AB和AC, AB为3, AC 为6,AB是A到其他点的最短距离,如果AC有可能更小的话,那么一定是经过B。原本A到C是6, 但经过B, ABC的距离是4.所以AC的最短距离是4.

所以怎么实现呢?

  1. 我们设置一个dis数组,来表示其他点到起点的最短距离。起点到起点的距离是0,所以dis[1] = 0, 其他点现在到起点的距离全部设为正无穷。
  2. 然后,我们要找到一个距离起点最近点。用一个循环遍历一下。
int t = -1; // 表示还没有处理过的距离起点最近的点。
// 找出距离起点最近的点。
for(int j = 1; j <= n; j++){
	if(st[j]==0 && (t==-1 || st[t] > st[j])
		t = j;
}

最终t就是我们找到的还没有处理过的距离起点最近的点。
处理的意思就是已经确定该点的最短路径。
然后通过t这个点,去缩短起点到达其他点的距离。

for(int j = 1; j <= n; j++){
	dis[j] = min(dis[j], dis[t] + w[t][j])
}

核心代码:

public static int Dijkstra(){
       Arrays.fill(dis, 0x3f3f3f3f);
        dis[1] = 0;
        for(int i = 0; i < n; i++){ // 循环n次, 每次找出一个离起点最近的点。
            int t = -1;
            for(int j = 1; j <= n; j++){
                if(S[j] == 0 && (t == -1 || dis[t] > dis[j])){ // 找到一个距离最短的加入S集合。
                    t = j;
                }
            }
            
            S[t] = 1;  // 然后通过这个点来缩短原点到达其他点的距离。
            for(int j = 2; j <= n; j++){
                dis[j] = Math.min(dis[j], dis[t] + w[t][j]);
            }
        }    
        
        if(dis[n] != 0x3f3f3f3f) return dis[n];
        else return -1;
    }    

例题:Dijkstra求最短路
在这里插入图片描述
JAVA代码:

import java.io.*;
import java.util.*;

public class 朴素Dijkstra{
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    static final int N = 505;
    static int w[][] = new int[N][N];
    static int dis[] = new int[N]; // 每个点距离原点的距离。
    static int S[] = new int[N]; // 最短路集合
    static int n,m;
    
    public static int Int(String s){
        return Integer.parseInt(s);
    }
    
    public static int Dijkstra(){
       Arrays.fill(dis, 0x3f3f3f3f);
        dis[1] = 0;
        for(int i = 0; i < n; i++){ // 循环n次, 每次找出一个离起点最近的点。
            int t = -1;
            for(int j = 1; j <= n; j++){
                if(S[j] == 0 && (t == -1 || dis[t] > dis[j])){ // 找到一个距离最短的加入S集合。
                    t = j;
                }
            }
            
            S[t] = 1;  // 然后通过这个点来缩短原点到达其他点的距离。
            for(int j = 2; j <= n; j++){
                dis[j] = Math.min(dis[j], dis[t] + w[t][j]);
            }
        }    
        
        if(dis[n] != 0x3f3f3f3f) return dis[n];
        else return -1;
    }    
    
    public static void main(String[] args) throws Exception{
        String s[] = in.readLine().split(" ");
        n = Integer.parseInt(s[0]);
        m = Integer.parseInt(s[1]);
        
        for(int i = 0; i < n; i++)
            Arrays.fill(w[i], 0x3f3f3f3f);
            
        for(int i = 0; i < m; i++){
            String s1[] = in.readLine().split(" ");
            int a, b, c;
            a = Int(s1[0]);
            b = Int(s1[1]);
            c = Int(s1[2]);
            w[a][b] = Math.min(w[a][b],c);
        }
        
        out.write(Dijkstra()+"\n");
        out.flush();
    }
}

堆优化Dijkstra

算法思想:

堆优化其实就是使用优先队列对图BFS一遍,在搜索的同时更新点的距离。
朴素算法需要遍历所有点找出距离最近的点,使用优先队列使这一步的时间复杂度从n变为了logn。
对于走迷宫问题,我们很容易可以使用BFS找出最短路,因为每个点与点之间的距离是一样的,但是当边权不同时,显然我们必须先遍历近距离的点,这时我们就可以使用优先队列来达到这一目的。

关键代码:

    public static int Dijkstra(){
    	Arrays.fill(dis, INF); // 初始化dis数组为正无穷
    	q.add(new Pair(0, 1)); // 将起点当做一个距离起点最近的点加入优先队列。
        dis[1] = 0; // 起点到起点的距离是0.
        while(!q.isEmpty()){  // 广度优先搜索 + 堆优化。
        	Pair t = q.poll();
        	if(S[t.a] == 1) continue;
        	S[t.a] = 1;
        	
        	for(int i = h[t.a]; i != 0; i = ne[i]){  //搜索当前点的所有邻接点。
        		if(dis[e[i]] > t.w + w[i]){ // 更新距离
        			dis[e[i]] = t.w + w[i];
        			q.add(new Pair(dis[e[i]], e[i]));
        		}
        	}
        }
        if(dis[n] != INF) return dis[n]; // 可以到达n号点
        else return -1; 
    }
}

还是上个题目使用堆优化来做:

import java.io.*;
import java.util.*;

class Pair{
    int w;
    int x;
    Pair(int a, int b){
        w = a;
        x = b;
    }
}

public class 堆优化Dijkstra{
    static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    
    static final int N = 100010, INF = 0x3f3f3f3f;
    static int n, m;
    static int[] w = new int[N], dis = new int[N];
    static int[] e = new int[N], ne = new int[N], h = new int[N], S = new int[N];
    static int idx = 1;
    
    static PriorityQueue<Pair> q = new PriorityQueue<>(11, new Comparator<Pair>(){
		public int compare(Pair a, Pair b) {  
        	return a.w - b.w; 
		}
    });//自定义类需要重写比较器
    
    public static void add(int a, int b, int c){
    	e[idx] = b;
    	w[idx] = c;
    	ne[idx] = h[a];
    	h[a] = idx++;
    }
    
    public static int Int(String s) {return Integer.parseInt(s);}
    
    public static int Dijkstra(){
    	Arrays.fill(dis, INF);
    	q.add(new Pair(0, 1));
        dis[1] = 0;
        while(!q.isEmpty()){  // 广度优先搜索 + 堆优化。
        	Pair t = q.poll();
        	if(S[t.x] == 1) continue;
        	S[t.x] = 1;
        	
        	for(int i = h[t.x]; i != 0; i = ne[i]){  // h[i]中存的是第i条个点指向的点。
        		if(dis[e[i]] > t.w + w[i]){
        			dis[e[i]] = t.w + w[i];
        			q.add(new Pair(dis[e[i]], e[i]));
        		}
        	}
        	
        }
        if(dis[n] != INF) return dis[n];
        else return -1;
    }
    
    public static void main(String[] args) throws Exception{
    	String s[] = in.readLine().split(" ");
    	n = Int(s[0]);
    	m = Int(s[1]);
    	for(int i = 0; i < m; i++){
    		String s1[] = in.readLine().split(" ");
    		add(Int(s1[0]), Int(s1[1]), Int(s1[2]));
    	}
    	out.write(Dijkstra()+"\n");
        out.flush();
    }
}

Bellman-Ford

算法思想:

Dijkstra算法是以一个距离起点最近的点为基准点,缩减其邻接点到起点的距离,是贪心思想。
而Bellman-Ford算法是先将每个点到达起点的距离设为正无穷,然后直接暴力枚举所有边,如果一个点的距离可以被更新,就更新该点的距离。枚举一次至少可以得到一个点到达起点的距离,直接无脑枚举n次,就可以得到所有点到起点的最短距离。
核心代码:

   void BellMan_Ford(){
        Arrays.fill(dist, 0x3f3f3f3f); // 初始化dis数组为正无穷
        dist[1] = 0;
        
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
            	int a = edge[j].a, b = edge[j].b, w = edge[j].w;
                if(dist[b] > dist[a] + t.w) //如果从a->b的距离加上dis[a] > dis[b] 则更新dis[b
                    dist[b] = dist[a] + t.w;
            }
        }
    }

可以看到最核心的就是两个for循环。手动画画图还是很好理解的。

求总路径条数不多于K条的最短路径

如果我们对Bellman-Ford算法进行一些限制,它就可以用来求有边数限制的最短路问题。

比如要求1到n的不多于1条边的最短路径,如果1不能直接到n,那么最短路径的边数一定是大于1的,此时就无解。
画个图:

在这里插入图片描述
用Bellman-Ford算法对求上图中1号点到3号点的最短路:

  for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                int a = edge[j].a, b = edge[j].b, w = edge[j].w;
                if(dist[b] > dist[a] + w) 
                    dist[b] = dist[a] + w;
            }
        }

第一次枚举所有边的过程中,先得到2号点到1号点的距离,然后得到3号点到一号点的距离。虽然外层循环只进行了一次,却得到了边数大于2的路径长度,这与我们想要得到边数不多于k条边的目的是冲突的,如果我们限制每次遍历所有边时最多只能修改某个点的直接后继,而不能修改一个点后继的后继,那么遍历所有边k次后,得到的结果就是边数不多于k条的最短路。

看图:

第一次遍历所有边:得到2,3的距离

在这里插入图片描述

第二次遍历所有边:得到4,6的距离
在这里插入图片描述
第三次遍历所有边:得到5的距离
在这里插入图片描述
怎么实现呢,很简单,对每个点的距离进行更新时,用上一次更新后的结果去更新就行了。需要加个辅助数组去存储上一次更新后点的位置。

 void BellmanFord(){
        Arrays.fill(dist, 0x3f3f3f3f);
        dist[1] = 0;
        int[] last = new int[N];
        for(int i = 0; i < k; i++){
            System.arraycopy(dist, 0, last, 0, m); //将dist赋值给last
            for(int j = 0; j < m; j++){
                Pair t = p[j];
                if(dist[t.b] > last[t.a] + t.x)
                    dist[t.b] = last[t.a] + t.x;
            }
        }
    }

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

Bellman-Ford算法时间复杂度很高,有人对其进行了优化,SPFA就是用队列优化版Bellman-Ford算法。

SPFA

我们知道Bellman-Ford是每次遍历所有边,如果一个点被搜索到了,就更新距离。 但是每一次遍历时是有一些点是无论如何都不会被搜索到的。这跟边的读入顺序有关。

比如读入:
2 3 1
1 2 1

代表2到3的距离是1, 1到2的距离是1

我们先存储的是2到3的边,所以就会先遍历2->3, 此时2和3到1的距离都是正无穷,所以3的距离不会被更新。

如果读入顺序是
1 2 1
2 3 1
我们一次循环就可以得到3号点的值。

算法思想:

我们在一次循环中做了很多不必要的操作,如果我们可以只更新那些前驱结点被更新过的点,就可以大大提升效率。因为只有前驱结点到达起点的距离减小了,它的后继结点到达起点的距离才能减小。

所以我们用宽搜的思想,每次将被更新过的点入队,然后遍历队列中每个点的后继结点,重复更新操作和入队操作。

虽然SPFA和堆优化版的Dijkstra很相似,但是两种搜索策略却是不同的。细细品。

核心代码:

  public static void SPFA(){
    	Arrays.fill(dis, 0x3f3f3f3f);
    	dis[1] = 0;
        q.add(1);
        while(!q.isEmpty()){
            int t = q.poll();
            s[t] = 0; //出对后标记为0,因为可能存在负权边,所以一个点可能会被更新多次,
            //所以一个点只要被更新过就能入队,次数不限
            
            for(int i = h[t]; i != 0; i = ne[i]){
                int j = e[i];
                if(dis[j] > dis[t] + w[i]){
                    dis[j] = dis[t] + w[i];
                    if(s[j] == 0){// 如果该点当前不在队中,就入队,避免重复操作。
                        q.add(j);
                        s[j] = 1; //标记已在队中
                    }
                }
            }
        }
    }
    

堆优化Dijkstra和SPFA的区别和优缺点

两者虽然很像,而且思想上也有一些相似,但终究是两种不同的算法,

Dijkstra是以一个距离起点最近的点为基础去修改其邻接点,堆优化后,要对一个点的所有边进行堆排序,然后每次从最近的点开始遍历。但是,如果存在负边权,就不能保证当前点到起点的距离是最短的。比如
1->2 = 1 , 1->3 = 2, 3->2 = -2,
那么1->2的最短距离其实是0,而不是1。这就是为什么DijkStra不能处理负权边。

SPFA则不对边排序, 而是一股脑的遍历一个被更新过的点的所有边。因为省去了堆排序这一步骤,大部分时候SPFA是要快于堆优化的Dijkstra的。

但是!! SPFA可能会被网格图等特殊构造的图卡成o(nm)的时间复杂度,所以一般还是要用堆优化Dijkstra。但是!!如果有负边权,那么就只能用SPFA了。


用SPFA判断负环

负环:
在这里插入图片描述
对于上图来说,1->2-> 3->1 就是一个负环,根据SPFA算法的性质,会将距离被更新过的点入队,因为存在负环,所以只要每次经过一次负环,所有点到起点的距离就会被不断减小,即SPFA就会陷入死循环,其他点到起点的距离最终会变为负无穷。
如果我们能找到一个条件,确定循环多少次后,就可以判断存在负环, 我们就可以强制结束SPFA,从而判断是否存在图中负环。
这个条件就是:

只要不存在负环,起点到达任意点所经过的边数一定小于n,反之一定大于等于n因为只有n个点,不经过环的话最多经过n-1条边,只有在存在负环的情况下,SPFA才会经过负环,经过负环后,到达其他点边数就会大于等于n,

代码:

public static int SPFA(){
    //因为目的是判断有无负环,所以先要将所有点都当做起点加入队列,因为一个图可能分成不连通的几部分,而负环存在于其中某一个连通块。
	for(int i = 1; i <= n; i++){
    	    q.add(i);
    	}
 
        while(!q.isEmpty()){// 这里不需要对dis数组初始化,因为存在负环的话距离会小于0.
            int t = q.poll();
            s[t] = 0;
            
            for(int i = h[t]; i != 0; i = ne[i]){
                int j = e[i];
                if(dis[j] > dis[t] + w[i]){
                    dis[j] = dis[t] + w[i];
                    cnt[j] = cnt[t] + 1;  // 将当前点到起点的距离+1
                    if(cnt[j] >= n){
                        return 1;
                    }
                    if(s[j] == 0){
                        q.add(j);
                        s[j] = 1;
                    }
                }
            }
        }
        return 0;
    }

Floyd

先说说Floyd的优点

Floyd算法用来求任意两点间的最短路,我们当然可以用上面说过的算法如SPFA,对一个图的每个点都当成起点,求其最短路,但如果是稠密图,其时间复杂度也会很高,而Floyd算法实现十分简单,还能再O(n^3)内完成

Floyd是本次所有算法中最短的了!
对于算法来说,代码长的不一定难懂,但短的一定不会很难懂。

算法思想:

对于朴素Dijkstra算法来说,起点通过距离它最近的点去缩短其到达其他点的距离,Floyd算法本质上也是这样的思想。
第一步 :通过一个点,遍历所有点对,更新距离。
第二步:通过n个点,遍历所有点对n次,更新距离。

核心代码:

void floyd()
{
    for (int k = 1; k <= n; k ++ ) //通过n个点
        for (int i = 1; i <= n; i ++ ) // 遍历所有点对。
            for (int j = 1; j <= n; j ++ )
                arr[i][j] = min(arr[i][j], arr[i][k] + arr[k][j]);
}

第一层循环就是枚举n个点, 内部两层循环来枚举所有点对。

总结

  1. 一定要画图。
  2. 一定要刷题。
  3. 写题的时候一定要注意是不是无向图, 无向图的话建边时要建一来一去两条,如果用邻接表存,数组一定要开足够大,至少是边数的两倍。
  4. 对于邻接矩阵,要判断重边。邻接表则不需要判断重边。

最短路题单:
https://vjudge.net/contest/66569
POJ 2387 Til the Cows Come Home
POJ 2253 Frogger
POJ 1797 Heavy Transportation
POJ 3268 Silver Cow Party
POJ 1860 Currency Exchange
POJ 3259 Wormholes
POJ 1502 MPI Maelstrom
POJ 3660 Cow Contest
POJ 2240 Arbitrage
POJ 1511 Invitation Cards
POJ 3159 Candies
POJ 2502 Subway
POJ 1062 昂贵的聘礼
POJ 1847 Tram
LightOJ 1074 Extended Traffic
HDU 4725 The Shortest Path in Nya Graph
HDU 3416 Marriage Match IV
HDU 4370 0 or 1
POJ 3169 Layout

以上题单源自Kuangbin专题

最短路问题(五个算法模板) 题目给定一个有向图,图中有 𝑛n 个点和 𝑚m 条边。图中可能存在重边和自环,所有边权均为正值。请你求出从 1 号点到 𝑛n 号点的最短距离。如果无法从 1 号点走到 𝑛n 号点,则输出 -1。 阅读详情

相关推荐

算法系列——四种最短路算法:Floyd,Dijkstra,Bellman-Ford,SPFA

写在前面: 好久没有更新博客了,距离上一次更新已经过去了十一个月了,一是因为课业繁重,二是因为这一年中接了不少项目。其实早就想写写算法和数据结构相关的文章了,之前在Coders群里也说过17年要多写写算法和数据结构,奈何计划赶不上变化,实在是没有工夫写。现在到了18年了,最近刚放寒假,数据科学导论实验今天交上了最后一个,总算是有些闲工夫了,准备写些东西却又不知道应该写什么,算法那么多,从哪个写起呢?思来想去,想到了最短路径算法,因为博主今年开了计算机网络课程,在计算机网络中,有一个很重要的东西就是路由,即

ITString的博客 892

最短路算法总结(超详细~)

文章目录最短路算法框架朴素Dijkstra算法堆优化版Dijkstra算法 最短路算法框架 最短路有五种算法,分别适用不同的情况。 单源最短路: 求一个点到其他点的最短路 多源最短路: 求任意两个点的最短路 稠密图用邻接矩阵存,稀疏图用邻接表存储。 稠密图: m 和 n2 一个级别 稀疏图: m 和 n 一个级别 朴素Dijkstra算法 Dijkstra算法是通过 n 次循环来确定 n 个点...

wmy0217_的博客 4万+

浅谈五种最短路算法(c++)

最短路问题,说人话就是给定一个图,求两个点之间所有走法中,边权和最短的路的值。总的来说,最短路算法分为5个不同的种类。 floyd 概述 floyed算法是多元最短路的算法(说人话:随便两个点我都能求),主要思想就是只要算的多就一定能做出来。 思路 每次找到一个点k,在遍历所有点,找到一对i,j,d[i][j]=min(d[i][j],d[i][k]+d[k][j]); 例题 题目描述 样例输入 时间复杂度分析 由循环易知,时间复杂度是O(n^3)。(200以上的数据就不要用了)

2301_79587247的博客 2104

最短路的四种算法

求最短路一般有四种方法: 1.dijkstra 邻接矩阵。 时间复杂度O(N^2) 2.dijkstra 邻接表+优先级队列优化。

tzw513的博客 1675

AI 编程助手新玩法:用 Claude Code 一键调用国产大模型(DeepSeek/Kimi/GLM 对比)

本文深入评测了Claude Code与三大国产大模型(DeepSeek、Kimi、智谱GLM)的集成效果,详细对比了它们在代码生成质量、响应速度和特殊场景支持度等方面的差异。通过实测数据和实战技巧,帮助开发者选择最适合的AI编程助手组合,提升开发效率。

weixin_30955617的博客 487

Flink CDC 3.0 详解

Flink CDC 是基于数据库日志 CDC(Change Data Capture)技术的实时数据集成框架,支持全增量一体化、无锁读取、并行读取、表结构变更自动同步、分布式架构等高级特性。配合Flink 优秀的管道能力和丰富的上下游生态,Flink CDC 可以高效实现海量数据的实时集成。Flink CDC 于2023年12月7日重磅推出其全新的 3.0 版本,3.0版本的发布对 Flink CDC 而言具有里程碑的意义,自此 Flink CDC 从捕获数据变更的Flink 数据源正式迈向为以 Flink

奔跑的蜗牛的博客 2639

【图论】最短路问题大合集,五种算法刷爆最短路问题。

思路:迭代n次,每次找到距离离起点最近的点,起点置为0,并且用距离最近的点更新其他点。题目:给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。输入格式:第一行包含整数 n 和 m。接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。输出格式:输出一个整数,表示 1 号点到 n 号点的最短距离。

m0_70875482的博客 1139

STC8H单片机ADC实战:从读取电位器到串口绘图,12位精度玩起来

本文详细介绍了STC8H单片机的ADC功能实战应用,从读取电位器到串口绘图,展示了12位精度的实现方法。通过硬件连接、代码配置、串口数据传输及高级优化技巧,帮助开发者快速掌握ADC模块的使用,适用于各种传感器数据采集和信号处理场景。

weixin_28278377的博客 345

最短路问题

文章目录最短路问题一.朴素dijkstra算法二.堆优化版dijkstra 算法三.Bellman-Ford算法四.spfa 算法五.floyd算法六.一些题目题1:信使题2:香甜的黄油题3:最小花费七.附录(四种解法模板,转载自[AcWing](https://www.acwing.com/blog/content/405/))1.朴素dijkstra算法2.堆优化版dijkstra3.Bellman-Ford算法4.spfa 算法5.floyd算法 最短路问题 序:最短路问题:求图中某个点到另一个点所

小皮皮LL的博客 865

WPS集成DeepSeek最新教程,附详细图文,让文案生成更智能

本文将为大家详细介绍如何将 DeepSeek 功能集成到 WPS 中,通过 OfficeAI 插件,你无需进行复杂的本地部署,只需通过官网连接即可快速启用 DeepSeek 强大的 AI 功能。不论是文案生成、翻译校对,还是深度推理、决策支持,DeepSeek 都能为你提供便捷的解决方案。让我们一起来看看如何操作吧!

Java徐师兄的博客 6万+

私有云平台搭建——OpenStack

私有云平台搭建——OpenStack 搭建过程

2301_79739036的博客 3091

gpt-ai-assistant 配置管理避坑指南:4 个关键参数与 5 个高频翻车问题

你带着 `NODE_ENV=development` 启动,在 LINE 里问什么,gpt-ai-assistant 都只回「OK!」。先别怀疑 API key 或模型坏了——这是它配置系统故意干的:非 production 环境会直接返回固定 mock。这也是 gpt-ai-assistant 配置管理里最典型的翻车现场:配置值不是没加载,而是被环境规则悄悄换掉了。不列参数清单了,下面跟着几个真

gitblog_00651的博客 291

【报错】raise pickle.UnpicklingError(_get_wo_message(str(e))) from None_pickle.UnpicklingError: Weigh

File "/opt/conda/envs/py_3.12/lib/python3.12/site-packages/torch/serialization.py", line 1470, in load raise pickle.UnpicklingError(_get_wo_message(str(e))) from None _pickle.UnpicklingError: Weights only load failed.

静谧、淡雅 785

[图+最短路+模板] 五大最短路常用模板

文章目录0. 前言1. 朴素 Dijkstra 算法求最短路2. 堆优化 Dijkstra 算法求最短路3. Bellman-Ford 算法求最短路 0. 前言 图论中最短路问题一般有两大类,然后在这两大类的基础上再细分为几个子项,下面简单梳理下知识点,总共 5 大最短路算法: 单源最短路: 源点,就是起点的意思。汇点,就是终点的意思。从一个点到所有点的最短距离。例,求解 1 号点到 n 号点的最短路,那么我们可以求解出从 1 号点到 n - 1 号点的所有最短路,那么显然,从 1 号点到 n 号点的最短

Y-puyu 的博客 1108

深度学习-161-Dify工具之对比使用工作流和聊天流生成图表可视化的html文件

分别使用聊天流和工作流进行数据分析结果的可视化,生成html文件。聊天流可以配置带记忆,这样就可以多次交互优化结果。

qq_20466211的博客 1709

RobotFramework二次开发——实时日志

背景基于RobotFramework的二次开发,少不了要打印实时日志出来,比如广泛应用的工具ride中,在执行用例时会把执行过程中的log全部打印出来,如果二次开发的时候,执行用例只能静默等待执行完毕,那只能算是一个半成品。结果在最后,不想看过程的可以直接跳到最后思路RobotFramework的日志有好几种,一个是执行后的log文件,这个文件可以作为数据留存,但是没办法实时获取,因为文件是在执行完

点点寒彬的博客 1万+

【图论最短路算法总结】

图论_最短路算法: Floyd Dijkstra Bellman-Ford SPFA Johnson 全源最短路 1. Floyd: ·时间复杂度:O(n3) ·使用范围:无负权回路的稠密图,应用于数据较小的题目,可以求出任意两点之间的最短路 memset(d,0x3f,sizeof d);//初始化 for(int k=1; k<=n; k++){//枚举中间点 for(int i=1; i<=n; i++){ if(i!=k) for(int

lovermaker的博客 283

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

三种最短路基本知识

三种最短路1:朴素dijkstra算法(1)算法原理(2)时间复杂度及适用情况(3)代码2:用堆栈优化的dijkstra算法(1)算法原理(2)时间复杂度及适用情况(3)代码3:Bellman-Ford算法(1)算法原理(2)时间复杂度及适用情况(3)代码4:SPFA算法(用队列优化的Bell)(1)算法原理(2)时间复杂度及适用情况(3)代码5:spfa证明是否存在负环(1)算法原理(2)时间复杂度及适用情况(3)代码6:Floyd算法(1)算法原理(2)时间复杂度及适用情况(3)代码 1:朴素dijks

qq_54783066的博客 260

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

深搜之迷宫类

常见的迷宫类搜索可以分为以下5种类型 1. 找一组可行解(判断是否可行) 2. 所有可行解 3. 最优解(通常见最少步数) 4. 计算连通块数目 5. 求最大连通块

JohnnyLin 2033

图论升级*

A. Codeforces 296D 重题 Code #include<bits/stdc++.h> using namespace std; const int maxn=503,INF=1050000000; int g[maxn][maxn],n,a[maxn]; long long ans[maxn]; long long floyd(int I){ long long...

weixin_30632089的博客 82

牛客周赛 Round 39vp(A--F)

我们对于 p 个编号为0,1,⋯,p−1 的点,进行连边:编号为 i 的点向编号为 (i+a1)%p....(i+an)%p​ 的点连边。首先参考牛客B站视频的DP过了95%(数据有点水),原因在于它有一点不同于完全背包,就是%p后可能变得跟小,因此我们还要回过头考虑前面的,因此在内部还要加一层循环。我们考虑预处理出su[i]表示走i步所要的min次数(注意这里的min只考虑了同一个物品,比如选1个还是选2个,不是选一个1再选一个2)带了懒标记的线段树,维护A,B以及A和B共有的1的即可。

cocoack的博客 415

DAIN视频插帧指南:3步本地跑出中间帧,x4慢动作一步到位

DAIN是一个深度感知的视频插帧模型,帮你在两帧相邻画面之间补出平滑的中间帧,也能生成x4、x8、x10的慢动作视频。按这篇的步骤做一遍,就能在本地编译好CUDA扩展、加载官方预训练权重,三步拿到第一批插帧结果。 ## DAIN解决什么问题:用深度消除中间帧的鬼影 视频帧率不够时,快速运动会产生鬼影和撕裂。DAIN显式检测画面里的遮挡(哪个物体被另一个物体挡住),利用深度线索判断谁离镜头近,在

gitblog_01182的博客 219

CSP 2016-9

1.最大波动 o(n) 模拟即可 #include<iostream> #include<cmath> #include<algorithm> using namespace std; #define N 1000 int a[N]; int main(){ int n; cin>>n; for(int i=0;i<n;i++) cin>>a[i]; int ans=0; for(int i=

Mj200644的博客 162

ZOJ 1649 Rescue (BFS)

题目大意:在一个矩阵里,有五种字符,一种是起点,一种是终点,一种代表墙不能走的,一种代表警卫需要花时间杀警卫的,最后一种代表路,每走一个格要花一个单位时间,杀一个警卫要花一个单位时间。求从起点到终点,花得最短时间! 分析:最短路径,其实很简单的,bfs搜索,然后判断一下是不是墙,是不是警卫和路,分别处理;在用一个数组d来记录每个点到起点的最短路径,同时也是用来标记已经遍历过的状态。 代码:

AClion的专栏 1074

LeetCode 743 Network Delay Time 全解法剖析:从 Dijkstra 到 SPFA 的最短路径实战指南

本篇指南以本仓库中 [network-delay-time 题解](https://link.gitcode.com/i/ce8f87a28a0325bf81a79bd2c0d099a4) 及其 [解题提示](https://link.gitcode.com/i/44cc5b0961dd30e6a1cdff3936eede03) 为主体,系统讲解 LeetCode 743 "Network Del

gitblog_06864的博客 154
上一篇: 深度优先搜索(DFS)和广度优先搜索(BFS)
下一篇: 二分法
Androids_lost_Sheep
博客等级 码龄8年 1022粉丝 86原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值