【codeforces 295B】Greg and Graph ( floyd )

传送门

    Greg and Graph
    题意:给出n个点,两两之间均存在有向边。按顺序删除指定点及其所有连边,求每次删除点之前图中现存任意两点间距离和。

I think

    时光倒流吧……
    题目要求的操作相当于从删除列表中最后一个点开始添加点,每次跑Floyd将用当前点更新的最短路添加至答案。

Code

#include<cstdio>
typedef long long LL;
const int sm = 505;
LL Ans[sm];
int N,g[sm][sm],del[sm];

void read(int &x) {
    x=0;char ch=getchar();
    while(ch>'9'||ch<'0') ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
}
void Floyd() {
    int K,I,J;
    LL t=0;
    for(int k=1;k<=N;++k) {
        K=del[k];
        for(int i=1;i<=N;++i)
            for(int j=1;j<=N;++j) {
                I=del[i],J=del[j];
                if(g[I][K]+g[K][J]<g[I][J])
                    g[I][J]=g[I][K]+g[K][J];
                if(i<=k&&j<=k) 
                    Ans[k]+=g[I][J];
            }
    }
}

int main() {
    read(N);
    for(int i=1;i<=N;++i)
        for(int j=1;j<=N;++j)
            read(g[i][j]);
    for(int i=N;i>=1;--i)
        read(del[i]); 
    Floyd();
    for(int i=N;i>=1;--i)
        printf("%I64d ",Ans[i]);
    putchar(10);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值