思路
删点不好做,不如到这做,把点一个一个得加入即可。
每次以第 $i$ 个点为中间点做 $\text{Floyd}$,最后把所有加入的点两两之间距离的和求出即可。
赛事脑抽了,把所有 $g_{i,j}$ 不为 $INF$ 都加上了。。。
代码
#include <iostream>
#include <cstring>
#include <unordered_set>
#include <vector>
typedef long long LL;
using namespace std;
const int N = 510;
int n;
LL g[N][N],b[N][N];
int x[N];
LL ans[N];
bool st[N];
void floyd (int x) {
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) {
g[i][j] = min (g[i][j],g[i][x] + g[x][j]);
}
}
}
int main () {
cin >> n;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= n;j++) cin >> g[i][j];
}
for (int i = 1;i <= n;i++) cin >> x[i];
for (int u = n;u >= 1;u--) {
st[x[u]] = true;
floyd (x[u]);
for (int i = 1;i <= n;i++) {
if (!st[i]) continue;
for (int j = 1;j <= n;j++) {
if (st[j]) ans[u] += g[i][j];
}
}
}
for (int i = 1;i <= n;i++) cout << ans[i] << ' ';
cout << endl;
return 0;
}