大意是n点有边权有向图,第i次操作删除图中的a[i]号节点以及其入边和出边,询问每次删除操作前剩余的点对间的最短路的权值的和。
n<=500
n=500,明显floyd
因为最后一个点也没有,离线后倒序处理操作
不断往图中加入点,并更新最短路
这道题加深了我对floryd的理解,外部循环加一其实是多考虑一个点的加入对图的最短路造成的影响,无所谓循环的顺序。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 505;
typedef long long LL;
LL a[maxn][maxn];
int x[maxn],vis[maxn];
LL ans[maxn];
int main(){
int n;
scanf("%d",&n);
for( int i = 1;i <= n;i++ ){
for( int j = 1;j <= n;j++ ){
scanf("%lld",&a[i][j]);
}
}
for( int i = 1;i <= n;i++ ) scanf("%d",&x[i]);
for( int t = n;t >= 1;t-- ){
int k = x[t];
vis[k] = 1;
for( int i = 1;i <= n;i++ ){
for( int j = 1;j <= n;j++ ){
a[i][j] = min( a[i][k]+a[k][j],a[i][j] );
if( vis[i] && vis[j] ) ans[t] += a[i][j];
}
}
}
for( int i = 1;i <= n;i++ ){
printf("%lld ",ans[i]);
}
return 0;
}