需要注意的是在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;
}