大意: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;
}