图论————最短路

这篇具有很好参考价值的文章主要介绍了图论————最短路。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

最短路

Dijkstra-朴素 O(n^2)

  1. 初始化距离数组, dist[1] = 0, dist[i] = inf;
  2. for n次循环 每次循环确定一个min加入S集合中,n次之后就得出所有的最短距离
  3. 将不在S中dist_min的点->t
  4. t->S加入最短路集合
  5. 用t更新到其他点的距离

Dijkstra-堆优化 O(mlogm)

  1. 利用邻接表,优先队列
  2. 在priorityqueue[HTMLREMOVED], greater[HTML_REMOVED] > heap;中将返回堆顶
  3. 利用堆顶来更新其他点,并加入堆中类似宽搜

Bellman_ford O(nm)

  1. 注意连锁想象需要备份, struct Edge{inta,b,c} Edge[M];
  2. 初始化dist, 松弛dist[x.b] = min(dist[x.b], backup[x.a]+x.w);
  3. 松弛k次,每次访问m条边

Spfa O(n)~O(nm)

  1. 利用队列优化仅加入修改过的地方
  2. for k次
  3. for 所有边利用宽搜模型去优化bellman_ford算法
  4. 更新队列中当前点的所有出边

Floyd O(n^3)

  1. 初始化d
  2. k, i, j 去更新d

模板:

  1. Dijkstra-朴素

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=150010;
    int n,m;
    int dist[N],e[N],ne[N],w[N],idx,h[N];
    bool st[N];
    #define PII pair<int,int>
    void add(int a,int b,int c){
        e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
    }
    int dj(){
        memset(dist,0x3f3f3f3f,sizeof dist);
        dist[1]=0;
        priority_queue<PII,vector<PII>,greater<PII>> heap;
        heap.push({0,1});
        while(heap.size()){
            auto t=heap.top();
            heap.pop();
            int ver=t.second,distance=t.first;
            if(st[ver]){
                continue;
            }
            st[ver]=true;
            for(int i=h[ver];i!=-1;i=ne[i]){
                int j=e[i];
                if(dist[j]>distance+w[i]){
                    dist[j]=distance+w[i];
                    heap.push({dist[j],j});
                }
            }
        }
        if(dist[n]==0x3f3f3f3f){
            return -1;
        }
        return dist[n];
    }
    int main(){
        cin>>n>>m;
        memset(h,-1,sizeof h);
        while(m--){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        cout<<dj();
    }
    
  2. Dijkstra-堆优化

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=150010;
    int n,m;
    int dist[N],e[N],ne[N],w[N],idx,h[N];
    bool st[N];
    #define PII pair<int,int>
    void add(int a,int b,int c){
        e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
    }
    int dj(){
        memset(dist,0x3f3f3f3f,sizeof dist);
        dist[1]=0;
        priority_queue<PII,vector<PII>,greater<PII>> heap;
        heap.push({0,1});
        while(heap.size()){
            auto t=heap.top();
            heap.pop();
            int ver=t.second,distance=t.first;
            if(st[ver]){
                continue;
            }
            st[ver]=true;
            for(int i=h[ver];i!=-1;i=ne[i]){
                int j=e[i];
                if(dist[j]>distance+w[i]){
                    dist[j]=distance+w[i];
                    heap.push({dist[j],j});
                }
            }
        }
        if(dist[n]==0x3f3f3f3f){
            return -1;
        }
        return dist[n];
    }
    int main(){
        cin>>n>>m;
        memset(h,-1,sizeof h);
        while(m--){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
        }
        cout<<dj();
    }
    
  3. Bellman_ford

    #include<iostream>
    #include<cstring>
    using namespace std;
    int n,m,k;
    const int N=100010;
    int dist[N],backup[N];
    struct node{
        int a,b,w;
    }edge[N];
    int b(){
        memset(dist,0x3f3f3f3f,sizeof dist);
        dist[1]=0;
        for(int i=0;i<k;i++){
            memcpy(backup,dist,sizeof backup);
            for(int j=1;j<=m;j++){
                int a=edge[j].a,b=edge[j].b,w=edge[j].w;
                dist[b]=min(dist[b],backup[a]+w);
            }
        }
        if(dist[n]>0x3f3f3f3f/2){
            return 0x3f3f3f3f;
        }
        return dist[n];
    }
    int main(){
        cin>>n>>m>>k;
        for(int i=1;i<=m;i++){
            int a,b,w;
            cin>>a>>b>>w;
            edge[i].a=a,edge[i].b=b,edge[i].w=w;
        }
        int t=b();
        if(t==0x3f3f3f3f){
            cout<<"impossible";
        }else{
            cout<<t;
        }
    }
    
  4. Spfa

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<queue>
    using namespace std;
    int n,m;
    const int N=100010;
    int dist[N];
    int idx,h[N],e[N],ne[N],w[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 spfa(){
        memset(dist,0x3f3f3f3f,sizeof dist);
        dist[1]=0;
        queue<int> q;
        q.push(1);
        st[1]=true;
        while(q.size()){
            int t=q.front();
            q.pop();
            st[t]=false;
            for(int i=h[t];i!=-1;i=ne[i]){
                int j=e[i];
                if(dist[j]>dist[t]+w[i]){
                    dist[j]=dist[t]+w[i];
                    if(!st[j]){
                        q.push(j);
                        st[j]=true;
                    }
                }
            }
        }
        if(dist[n]==0x3f3f3f3f){
            return -2;
        }
        return dist[n];
    }
    int main(){
        cin>>n>>m;
        memset(h,-1,sizeof h);
        while(m--){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
        }
        int t=spfa();
        if(t==-2){
            cout<<"impossible";
        }else{
            cout<<dist[n];
        }
    }
    
  5. Floyd文章来源地址https://www.toymoban.com/news/detail-608406.html

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int N=210;
    int f[N][N],n,m,k;
    void floyd(){
        for(int k=1;k<=n;k++){
            for(int i=1;i<=n;i++){
                for(int j=1;j<=n;j++){
                    f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
                }
            }
        }
    }
    int main(){
        cin>>n>>m>>k;
        for(int i=1;i<=200;i++){
            for(int j=1;j<=200;j++){
                if(i==j){
                    f[i][j]=0;
                }else{
                    f[i][j]=0x3f3f3f3f;
                }
            }
        }
        while(m--){
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            f[a][b]=min(f[a][b],c);
        }
        floyd();
        while(k--){
            int a,b;
            cin>>a>>b;
            if(f[a][b]>0x3f3f3f3f/2){
                puts("impossible");
            }else{
                cout<<f[a][b]<<endl;
            }
        }
    }

到了这里,关于图论————最短路的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 12.图论1 最短路之dijkstra算法

    二分图 判定:染色法。 性质: 可以二着色。 无奇圈。 树的直径模板 两遍dfs/bfs,证明时反证法的核心是用假设推出矛盾。 设1是一开始随机选的点,s是与其最远的点,证明s是直径的一端。 反证:假设s不是直径的一端,ss是直径的一端。 现在要做的就是证明ss是直径的一端

    2024年02月20日
    浏览(47)
  • 算法提高-图论-单源最短路的扩展应用

    多源点单终点最短路建图: 创建虚拟源点(创建虚拟源点的时候以是spfa为例 可以在建图的时候建出来,也可以在spfa这直接入队,也是虚拟源点的意思) 反向建图变成单源点多终点,然后遍历终点的dist即可找出最短路 这题挺简单的就不详细说了,主要是第一次遇到计数问题

    2024年02月16日
    浏览(48)
  • 算法提高-图论-单源最短路的综合应用

    多次dijkstra求每个点到其它点的最短距离, 此时相当于建好了一张图,每个点之间的最短距离都知道了,接下来dfs搜一下怎么走最短即可 一篇博客解释了为什么一个正向建图求最小值,反向建图求最大值 根本思想是保证1到n的买卖是连通的

    2024年02月11日
    浏览(75)
  • 图论算法基础:单源最短路径Dijkstra算法分析

    在 有向带权图 中给定一个起始顶点(源点),Dijkstra算法可以求出 所有其他顶点 到源点的最短路径,Dijkstra算法 不能用于同时含有正负权值的边的图 Source 顶点集合:已经确定 到源点的最短路径 的顶点就会加入 Source 集合中, Source 集合初始时只有源点 dist 数组:用于记录每个顶点到

    2024年02月11日
    浏览(44)
  • 图论与算法(遍历、最小生成树、最短路径)

    图是由顶点集合及顶点间的关系组成的一种数据结构:G = (V, E),其中:顶点集合V = {x|x属于某个数据对象集}是有穷非空集合;E = {(x,y)|x,y属于V}或者E = {x, y|x,y属于V Path(x, y)}是顶点间关系的有穷集合,也叫做边的集合。(x, y)表示x到y的一条双向通路,即(x, y)是无方向的;Path

    2024年04月14日
    浏览(45)
  • 图论:最短路(dijkstra算法、bellman算法、spfa算法、floyd算法)详细版

    终于是学完了,这个最短路我学了好几天,当然也学了别的算法啦,也是非常的累啊。 话不多说下面看看最短路问题吧。 最短路问题是有向图,要求的是图中一个点到起点的距离,其中我们要输入点和点之间的距离,来求最短路。 下面分为几类题目: 单源汇最短路--一个起

    2024年01月21日
    浏览(44)
  • 算法提高-图论-单源最短路的建图方式

    建图 找出一个牧场,它到其他牧场的距离之和最小 我是这么理解的,djsktra是一个贪心的思想,加法里面不能加负数我就不说了 求乘法最大值的时候为什么边权必须0-1,因为在乘法最大值里面有一个边权大于1的话那不就等价于求加法最小值的时候有一个边权为负数的么,d

    2024年02月08日
    浏览(45)
  • 图论14-最短路径-Dijkstra算法+Bellman-Ford算法+Floyed算法

    https://github.com/Chufeng-Jiang/Graph-Theory/tree/main/src/Chapter11_Min_Path 2.4.1 判断某个顶点的连通性 2.4.2 求源点s到某个顶点的最短路径 存放节点编号和距离 这里的缺点就是,更新node时候,会重复添加节点相同的node,但是路径值不一样。不影响最后结果。 更新pre数组 输出路径 初始化两

    2024年02月04日
    浏览(36)
  • 【算法每日一练]-图论(保姆级教程 篇4(最短路,分层图) #最短路计数 #社交网络 #公园 #飞行路线 # 第二短路

    目录 今天知识点   di和sp求到每个点的最短路数  floyd求到点的最短路数和经过点的最短路数 求三点最短距离 每个点有多个状态,建立分层图 求第二短路 题目:最短路计数 思路: 题目:社交网络 思路: 题目:公园 思路: 题目:飞行路线  思路: 题目:第二短路 思路:

    2024年02月04日
    浏览(42)
  • 28. BI - 图论工具和算法, 社区发现以及最短路径

    本文为 「茶桁的 AI 秘籍 - BI 篇 第 28 篇」 Hi, 我是茶桁. 咱们已经讲了好几节课的 PageRank, 也了解了 PageRank 的原理就是基于图论. 之前我有给讲过, 在「数学篇」中我们有用四个章节来详细的讲解图论的相关知识。其中包括: 23. 图论 - 图的由来和构成 24. 图论 - 图的表示种类

    2024年04月15日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包