首页 > 其他分享 >最短路合辑

最短路合辑

时间:2023-04-17 11:48:20浏览次数:49  
标签:src memset dist int 短路 合辑 inq sizeof

  1. Dijkstra算法,堆优化版本复杂度是mlog(m)。适合于没有负权的图。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    using LL = long long;
    
    const int N  = 1e5 + 5;
    
    const int INF = 0x3f3f3f3f;
    
    vector<pair<int,int>> G[N];
    
    int vis[N];
    int dist[N];
    
    void dij(int s){
        memset(vis,0,sizeof(vis));
        memset(dist,INF,sizeof(dist));
    
        priority_queue<pair<int,int>> q;
        q.push({0, s});
        dist[s]=0;
        while(!q.empty()){
            auto u = q.top().second;
            q.pop();
    
            if(vis[u])continue;
            vis[u]=1;
    
            for(auto &e:G[u]){
                int v=e.first;
                int w=e.second;
                if(dist[u] + w < dist[v]){
                    dist[v] = dist[u] + w;
                    q.push(make_pair(-(dist[u] + w), v));
                }
            }
        }    
    }
    
    int n, m, src;
    
    int main(){
        cin >> n >> m >> src;
        for(int i=0;i<m;++i){
            int x, y, w;
            cin >> x >> y >> w;
            G[x].push_back(make_pair(y,w));
            G[y].push_back(make_pair(x,w));
        }
    
        dij(src);
        for(int i=1;i<=n;++i){
            if(dist[i] < 1e8) cout<<dist[i]<<" ";
            else cout<<"-1 ";
        }
    
        
        return 0;
    }
    

    这个题目能让dijkstra的理解深刻一点(主要是它的正确性)。https://leetcode.cn/problems/path-with-maximum-probability/

  2. Bellman_ford算法,复杂度O(n*m)。适用于有负权的情况。复杂度高。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    using LL = long long;
    
    const int N  = 1e5 + 5;
    
    const int INF = 0x3f3f3f3f;
    
    vector<pair<int,int>> G[N];
    
    int dist[N];
    
    int n, m, src;
    
    int bellman_ford(int s){
        memset(dist,INF,sizeof(dist));
        dist[s]=0;
    
        for(int i=1;i<n;++i){ //n-1轮更新
            for(int u=1;u<=n;++u){
                if(dist[u]==INF){continue;}
                for(auto& p:G[u]){
                    int v=p.first, w=p.second;
                    if(dist[v]>dist[u]+w){
                        dist[v]=dist[u]+w;
                    }
                }
            }
        }
    
        for(int u=1;u<=n;++u){
            for(auto& p:G[u]){
                int v=p.first, w=p.second;
                if(dist[v]>dist[u]+w){
                    dist[v]=dist[u]+w; // n轮之后还能更新
                    return 0;
                }
            }
        }
    
        return 1;    
    }
    
    int main(){
        cin >> n >> m >> src;
        for(int i=0;i<m;++i){
            int x, y, w;
            cin >> x >> y >> w;
            G[x].push_back(make_pair(y,w));
        }
    
        bellman_ford(src);
        for(int i=1;i<=n;++i){
            if(dist[i] < 1e8) cout<<dist[i]<<" ";
            else cout<<"-1 ";
        }
        return 0;
    }
    
  3. SPFA算法。最差复杂度与bellman ford一样。但是最好复杂度是O(M)。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    using LL = long long;
    
    const int N  = 1e5 + 5;
    
    const int INF = 0x3f;
    
    int dist[N], inq[N];
    
    int n, m, src;
    
    int head[N], nxt[N], to[N], weight[N];
    int cnte=0;
    
    int neg_loog[N];
    
    void add_edge(int x, int y, int w){
        to[++cnte]=y;
        weight[cnte]=w;
        nxt[cnte]=head[x];
        head[x]=cnte;
    }
    
    int spfa(int s){ // return 0 if neg loop;    
        queue<int> q;
        q.push(s);
        dist[s]=0;
        inq[s]=1;
        neg_loog[1]=1;
        while(!q.empty()){
            int u=q.front();
            q.pop();
            inq[u]=0;
    
            for(int e=head[u];e;e=nxt[e]){
                int v=to[e], w=weight[e];
                if(dist[v]>dist[u]+w){
                    dist[v]=dist[u]+w;
                    if(!inq[v]){
                        if(++neg_loog[v]>=n){ //某一个点入队n次及以上,就是有负环。
                            return 0;
                        }
                        inq[v]=1;
                        q.push(v);
                    }
                }
            }
        }
        return 1;
    }
    
    void init(){
        cnte=0;
        memset(head,0,sizeof(head));
        memset(neg_loog,0,sizeof(neg_loog));
        memset(dist,INF,sizeof(dist));
        memset(inq,0,sizeof(inq));
    
    }
    
    int main(){
        int t;cin>>t;
        while(t--){
            cin >> n >> m;
            src=1;
            init();
            for(int i=0;i<m;++i){
                int x, y, w;
                cin>>x>>y>>w;
                if(w<0){
                    add_edge(x, y, w);
                }
                else{
                    add_edge(x, y, w);
                    add_edge(y, x, w);
                }
            }
    
            if(!spfa(src)){
                cout<<"YES"<<endl;
            }else{
                cout<<"NO"<<endl;
            }
        }
       
        return 0;
    }
    
  4. floyd算法。复杂度O(N^ 3),只需要记得要先枚举中间节点。

标签:src,memset,dist,int,短路,合辑,inq,sizeof
From: https://www.cnblogs.com/JohnRan/p/17325336.html

相关文章

  • 2642. 设计可以求最短路径的图类
    题目链接:2642.设计可以求最短路径的图类方法一:Dijkstra解题思路每次调用\(shortestPath(st,ed)\)时,就通过\(Dijkstra\)算法计算\(st\)->\(ed\)的最短路。代码朴素写法classGraph{private:vector<vector<int>>adj;inte[110][110],n;public:G......
  • Dijkstra算法求最短路
    一、Dijkstra 只适用于单源最短路中所有边权都是正数的情况二、存储方式1、稠密图用邻接矩阵2、稀疏图用邻接表三、算法实现用一个dist数组保存源点到其余各个节点的距离,dist[i]表示源点到节点i的距离。将dist数组赋值为正无穷,dist[1]=0用......
  • UVA 12295 Optimal Symmetric Paths 最短路求方案数
    题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=23587题意:给一个n*n的矩阵,每个方格中有一个数字,从左上角走到右下角,且路径必须关于副对角线对称,求使路线上数字和最小的方案数思路:既然要关于副对角线对称,那么可以把关于副对角线对称的方格的值加到一起去,这样就......
  • LeetCode 周赛 340,质数 / 前缀和 / 极大化最小值 / 最短路 / 平衡二叉树
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。大家好,我是小彭。上周跟大家讲到小彭文章风格的问题,和一些朋友聊过以后,至少在算法题解方面确定了小彭的风格。虽然竞赛算法题的文章受众非常小,但却有很多像我一样的初学者,他们有兴趣参加但容易被题目难......
  • Codeforces Round #303 (Div. 2) E. Paths and Trees (最短路+变形最小生成树)
    题目地址:E.PathsandTrees模拟了一场CF,这场实在太水了。。边玩边做的。。最后半分钟交了一发E题。。不幸AK绝杀失败。。。。首先的思路肯定是先求最短路,把可能为最短路的边挑出来,然后第二步我本来写的是直接用无向图的最小生成树,于是绝杀失败。。。后来才发现这样是不行的。......
  • (CCPC F题)UESTC 1220 The Battle of Guandu (最短路)
    题目地址:UESTC1220比赛的时候翻译完想了一小会就没再管。结果K题也没调试出来。。这题是很神奇的图论题,建图方式是从y[i]到x[i]连一条有向边,权值为c[i]。然后将所有重要性为0的设为源点,然后跑最短路,结果就是所有重要性为2的点的最短距离。实在是不好解释和证明这种建图的正......
  • Codeforces Round #Pi (Div. 2) E. President and Roads (最短路+强连通求割边)
    题目地址:codeforces#pi(DIV2)E题目很水。。就是先求两边最短路,然后把可能为最短路的边挑出来,然后判断是否yes只需要转化成无向图跑一遍tarjan,找出割边,割边就是yes,然后剩下的边就让它的值为最短路-1就行了,如果-1后变成了非正数,就是no.但是!!!居然卡spfa!!那是不是说cf以后就不......
  • m基于GA遗传优化和OSPF协议的WSN最短路由算法matlab仿真,并输出节点的不同层域
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要2.1GA遗传优化        GA把问题的解表示成“染色体”,在算法中也即是以二进制编码的串。并且,在执行遗传算法之前,给出一群“染色体”,也即是假设解。然后,把这些假设解置于问题的“环境”中,并按......
  • 利用强化学习Q-Learning实现最短路径算法
    如果你是一名计算机专业的学生,有对图论有基本的了解,那么你一定知道一些著名的最优路径解,如Dijkstra算法、Bellman-Ford算法和a*算法(A-Star)等。这些算法都是大佬们经过无数小时的努力才发现的,但是现在已经是人工智能的时代,强化学习算法能够为我们提出和前辈一样好的解决方案吗?......
  • spfa求最短路——BFS,数组实现邻接表,数组实现队列
    题目描述题目来源AcWing给定一个n个点m条边的有向图,图中可能存在重边和自环,边权可能为负数。请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出impossible。数据保证不存在负权回路。输入格式第一行包含整数n和m。接下来m行每行包含三个......