P5905 【模板】全源最短路(Johnson)
题解
发誓以后除了stl内置,其他时候结构体绝对不内置比较函数


code
#define ll long long
#include<bits/stdc++.h>
using namespace std;
ll in_q[3005]={0};
ll h[3005]={0};
ll vis[3005]={0};
ll dis[3003]={0};
const ll inf=1e9;
struct
{
ll to,val,head;
}edge[9005];
int len=0;
int last[9005]={0};
struct fresh
{
ll to,val;
bool operator<(const fresh &b)const {return b.val<val;}//代表降序
};
void add(int now,int to,int val)
{
edge[++len].to=to;
edge[len].val=val;
edge[len].head=last[now];
last[now]=len;
}
inline void read(ll &x) {
x = 0;
ll flag = 1;
char c = getchar();
while(c < '0' || c > '9'){
if(c == '-')flag = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = (x << 3) + (x << 1) + (c ^ 48);
c = getchar();
}
x *= flag;
}
inline void write(ll x)
{
if(x < 0){
putchar('-');
x = -x;
}
if(x > 9)
write(x / 10);
putchar(x % 10 + '0');
}
ll n,m;
ll fh()
{
queue<ll> q;
memset(h,0x3f,sizeof h);
h[0]=0;
q.push(0);
in_q[0]=1;
vis[0]=1;
while(q.size())
{
ll now=q.front();
q.pop();
in_q[now]=0;
for(int i=last[now];i;i=edge[i].head)
{
ll to=edge[i].to,val=edge[i].val;
if(h[to]>h[now]+val)
{
h[to]=h[now]+val;
if(!in_q[to])
{
q.push(to);
vis[to]++;
in_q[to]=1;
}
if(vis[to]>n) return 0;
}
}
}
return 1;
}
void dijk(ll x)
{
fill(dis + 1, dis + n + 1, inf);
priority_queue<fresh> q;
q.push({x,0});
while(q.size())
{
ll now=q.top().to,val=q.top().val;
q.pop();
if(val>=dis[now])continue;
dis[now]=val;
for(int i=last[now];i;i=edge[i].head)
{
ll to=edge[i].to,tov=edge[i].val;
if(dis[to]>dis[now]+tov)
{
q.push({to,tov+dis[now]});
}
}
}
}
int main()
{
read(n); read(m);
for(ll i=1;i<=m;i++)
{
ll x,y,w;
read(x); read(y); read(w);
add(x,y,w);
}
for(ll i=1;i<=n;i++) add(0,i,0);
if(!fh())
{
write(-1); putchar('\n');
return 0;
}
for(ll i=1;i<=n;i++)
{
for(int j=last[i];j;j=edge[j].head)
{
edge[j].val+=h[i]-h[edge[j].to];
}
}
for(ll i=1;i<=n;i++)
{
dijk(i);
ll ans=0;
for(ll j=1;j<=n;j++)
{
if(dis[j]==inf)
{
ans+=inf*j;
}
else ans+=j*(dis[j]+h[j]-h[i]);
}
write(ans); putchar('\n');
}
return 0;
}

浙公网安备 33010602011771号