[Codeforces 295B]Greg and Graph(Floyd)

时间:2023-02-02 11:04:35

链接

大意:n个点的有向图,给你一个n的排列,要求你按照顺序删除图中的点,并且计算出每次删除后图中点对的最短路之和

首先将删点改为加点
设新加入的点为x,则我们枚举u,v(都是从1到n),然后更新
a[u][v] = min(a[u][v], a[u][x] + a[x][v]);
这样一来只要计算答案时,枚举的u,v都是当前已经加入的点,就能保证计算的所有最短路经过的点都是当前存在的点。

#include<iostream>
#include<cstdio>
using namespace std;
#define ll long long

const int maxn = 600;
int n;
ll a[maxn][maxn],p[maxn],sum[maxn];

int main() {
    cin>>n;
    for(int i = 1; i <= n; i++) {
        for(int j = 1; j <= n; j++) {
            cin>>a[i][j];
        }
    }
    for(int i = 1; i <= n; i++)  cin>>p[n - i + 1]; 
    for(int k = 1; k <= n; k++) {
        ll ans = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                a[p[i]][p[j]] = min(a[p[i]][p[k]] + a[p[k]][p[j]], a[p[i]][p[j]]);
                if(i <= k && j <= k) ans+=a[p[i]][p[j]];
            }
        }
        sum[n-k + 1] = ans;
    }
    for(int i =1; i <= n; i++) cout<<sum[i]<<' ';
    return 0;
}