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;
}

posted @   纯粹的  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示