P5905 【模板】Johnson 全源最短路

需要注意的是在bellman-ford跑完后要把原来存好的边权给改一下,最后算最终的时候给减回来。

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=3e3+100;
const int inf=1e9;
typedef long long LL;
typedef pair<LL,LL> P;
inline LL read(){
    
    LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){
    
    if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){
    
    x=x*10+ch-48;ch=getchar();}
return x*f;}
struct Edge{
    
    
    LL u,v,w;
    Edge(LL _u=0,LL _v=0,LL _w=0)
        :u(_u),
         v(_v),
         w(_w)
    {
    
    }
}edges[maxn*2+maxn];
vector<P>g[maxn];
bool vis[maxn];
LL d1[maxn],dis[maxn][maxn],tot=0,n,m;
inline int bellman_ford(LL st){
    
    
    fill(d1,d1+maxn,inf);
    d1[st]=0;
    for(int i=1;i<n;i++){
    
    
        for(int j=1;j<=tot;j++){
    
    
            if(d1[edges[j].v]>d1[edges[j].u]+edges[j].w){
    
    
                d1[edges[j].v]=d1[edges[j].u]+edges[j].w;
            }
        }
    }
    for(int j=1;j<=tot;j++){
    
    
        if(d1[edges[j].v]>d1[edges[j].u]+edges[j].w) return -1;
    }
    return 1;
}
void dijkstra(LL st){
    
    
     memset(vis,0,sizeof(vis));
     priority_queue<P,vector<P>,greater<P>>que;
     que.push({
    
    0,st});
     dis[st][st]=0;
     while(!que.empty()){
    
    
        P now=que.top();que.pop();
        LL u=now.second;
        if(vis[u]) continue;
        vis[u]=true;
        for(int i=0;i<g[u].size();i++){
    
    
            LL v=g[u][i].first;LL val=g[u][i].second;
            if(dis[st][v]>dis[st][u]+val){
    
    
               dis[st][v]=dis[st][u]+val;
               que.push({
    
    dis[st][v],v});
            }
        }
     }
}
int main(void){
    
    
   	cin.tie(0);std::ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=m;i++){
    
    
        LL u,v,w;cin>>u>>v>>w;
        g[u].push_back({
    
    v,w});
        edges[++tot]=Edge(u,v,w);
    }
    for(int i=1;i<=n;i++){
    
    
        edges[++tot]=Edge(0,i,0);
    }
    int flag=bellman_ford(0);
   	if(flag==-1){
    
    ///存在负环
        cout<<"-1"<<endl;
   	}
   	else{
    
    
        for(int i=1;i<=n;i++){
    
    
            for(int j=0;j<g[i].size();j++) g[i][j].second+=d1[i]-d1[g[i][j].first];
        }
        fill(dis[0],dis[0]+maxn*maxn,inf);
        for(int i=1;i<=n;i++){
    
    
            dijkstra(i);
        }
        for(int i=1;i<=n;i++){
    
    
            LL res=0;
            for(int j=1;j<=n;j++){
    
    
                if(dis[i][j]==inf) res+=j*dis[i][j];
                else res+=j*(dis[i][j]-(d1[i]-d1[j]));
            }
            cout<<res<<endl;
        }
   	}
   	return 0;
}

猜你喜欢

转载自blog.csdn.net/zstuyyyyccccbbbb/article/details/121305868
今日推荐