首页 > 其他分享 >Johnson全源最短路

Johnson全源最短路

时间:2024-08-14 23:05:47浏览次数:8  
标签:cnt Johnson int 全源 ford Floyd 短路

Johnson全源最短路

引入

对于一个无负环的图,我们可以用Floyd或n遍Bellman-ford求出它的全源最短路
Floyd复杂度为O(\(n^3\))在稀疏图上效率极低
n遍Bellman-ford O(\(n^2m\))效率远不及 Floyd
注意到n遍dijstra复杂度为O(\(nm~log~m\))或O(\(n^3\))快于Floyd
但无法在负权图上跑,考虑对边进行重新赋值,使之为非负数

Johnson


注:最终答案\(dis_{i,j}\)为新图上\(dis_{i,j}-h{i}+h_{j}\)

Code

lougu P5905
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,h[3010],cnt;
struct node{
    int to,d;
    bool operator < (const node &rhs) const{
        return d>rhs.d;
    }
};
priority_queue<node>q;
struct edge{
    int u,v,d,nxt,rd;
}e[9010];   //链式前向星
int hd[3010];
void add(int u,int v,int d){
    e[++cnt].d=d;e[cnt].v=v;
    e[cnt].nxt=hd[u];e[cnt].u=u;
    hd[u]=cnt;
}
bool bellman_ford(){      //计算h[u]
    for(int i=1;i<=n;i++) add(0,i,0);
    for(int i=1;i<=n;i++) h[i]=1e9;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=cnt;j++){
            int u=e[j].u,v=e[j].v,d=e[j].d;
            h[v]=min(h[v],h[u]+d);
        }
    }
    for(int j=1;j<=cnt;j++){
        int u=e[j].u,v=e[j].v,d=e[j].d;
        if(h[v]>h[u]+d) return 1;
    }
    for(int i=1;i<=m;i++) e[i].rd=e[i].d+h[e[i].u]-h[e[i].v];
    return 0;
}
int vis[3010],dis[3010],f[3010][3010];
void dijstra(int s){
    for(int i=1;i<=n;i++) vis[i]=0,dis[i]=1e9;
    q.push({s,0});
    dis[s]=0;
    while(!q.empty()){
        int u=q.top().to,d=q.top().d;
        q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(int i=hd[u];i!=0;i=e[i].nxt){
            int v=e[i].v,ds=e[i].rd;
            if(dis[v]>d+ds){
                dis[v]=d+ds;
                q.push({v,d+ds});
            }
        }
    }
    for(int i=1;i<=n;i++) if(dis[i]!=1e9)f[s][i]=dis[i]-h[s]+h[i];else f[s][i]=1e9;
}
signed main(){
    cin>>n>>m;
    for(int i=1,x,y,o;i<=m;i++){
        cin>>x>>y>>o;
        add(x,y,o);
    }
    if(bellman_ford()){
        cout<<"-1";
        return 0;
    }
    for(int i=1;i<=n;i++) dijstra(i);
    int sum;
    for(int i=1;i<=n;i++){
        sum=0;
        for(int j=1;j<=n;j++){
            sum+=j*f[i][j];
        }
        cout<<sum<<endl;
    }
    return 0;
}

标签:cnt,Johnson,int,全源,ford,Floyd,短路
From: https://www.cnblogs.com/grylls2012/p/18359935

相关文章

  • 最短路算法
    存在最短路的前提不存在负环。链接还是OIWiki好啊~~Floyd算法两两间最短路,可判负环。时间复杂度\(O(n^3)\)。像DP的思路一样。设\(f_{k,x,y}\)表示允许经过\(1\simk\)的点,\(x\toy\)的最短距离。\(O(n^3)\)的DP即可。按照\(k,x,y\)的顺序循环,每次与\(......
  • 「Day 5—最短路径」
    最短路问题单源最短路全源最短路Floyd算法通过转移方程判断i->j的路径中,是否有i->k->j更短,运用简单dp来转移状态。f[i][j]表示i->j的最短路径长度。但不要忘了初始化,一个点到其本身的最短路径为1,即f[i][i]=1,其余的初始化为'1e9'即可。for(inti=......
  • 【学习笔记】Matlab和python双语言的学习(图论最短路径)
    文章目录前言一、图论基本概念示例二、代码实现----Matlab三、代码实现----python总结前言通过模型算法,熟练对Matlab和python的应用。学习视频链接:https://www.bilibili.com/video/BV1EK41187QF?p=36&vd_source=67471d3a1b4f517b7a7964093e62f7e6一、图论图论(G......
  • 算法板子:最短路问题——包含朴素Dijkstra算法、堆优化版的Dijkstra算法、SPFA算法、Fl
    目录1.几种算法的用途2.Dijkstra算法——求源点到其他所有点的最短路径(不能处理负边权)(1)朴素Dijkstra算法——适用于稠密图(2)堆优化版的Dijkstra算法——适用于稀疏图4.SPFA算法——求源点到其他所有点的最短路径、判断是否存在负环(可以处理负边权)(1)求有负边权的图......
  • 最短路
    最短路算法框架单源最短路:求一个点到其他点的最短路多源最短路:求任意两点的最短路稠密图用邻接矩阵存,稀疏图用邻接表来存。稠密图:m和n2一个级别稀疏图:m和n一个级别dijkstra算法朴素版用来求一个源点到其他点的最短距离#include<bits/stdc++.h>usingnamespacestd;str......
  • 次短路和第 k 短路
    次短路和第k短路次短路在最短路的基础上,次短路可以由次短路\(~+~\)边更新,也可以由最短路$~+~边更新,这里注意一点,因为次短路更新时也会对其它次短路产生影响,所以更新次短路时也需要入队,我们先尝试更新最短路,成功的话就把原来的最短路给次短路,不成功的话就单独尝试更新次短路......
  • 【变压器的短路试验】变压器的短路试验是通过将二次侧短路,并向一次侧施加额定电流来进
       ......
  • Studying-代码随想录训练营day62| Floyd 算法精讲、A*算法精讲(A star算法)、最短路算法
    第62天,完结撒花*★,°*:.☆( ̄▽ ̄)/$:*.°★*,最后的两个算法学习,编程语言C++目录Floyd算法精讲A*算法精讲(Astar算法) A*算法 复杂度分析 A*算法的缺点最短路算法总结篇 图论总结深搜和广搜并查集最小生成树 拓扑排序 最短路算法 总结 Floyd算法精讲......
  • 代码随想录算法训练营第62天 | 最短路径:dijkstra(堆优化版)+ Bellman_ford算法
    47.参加科学大会https://kamacoder.com/problempage.php?pid=1047dijkstra(堆优化版)精讲https://www.programmercarl.com/kamacoder/0047.参会dijkstra堆.html#思路94.城市间货物运输Ihttps://kamacoder.com/problempage.php?pid=1152Bellman_ford算法精讲https://www.pr......
  • 关于最短路
    定义单源最短路:从一个点出发,到其他所有点的最短距离多源最短路:从图中任意一点出发,到其他所有点的最短距离记号\(n~\)为图上点的数目,\(m~\)为图上边的数目;\(s~\)为最短路的源点;\(D(u)~\)为\(~s~\)点到\(~u~\)点的实际最短路长度;\(~dis(u)~\)为s点到u点的估计最短......