<题目链接>
题目大意:
给定$n$个点的有向完全带权图$(nleq500)$,现在进行$n$次操作,每次操作从图中删除一个点(每删除一个点,都会将与它相关联的边都删除),问你每次删点之前,图中所有点对的最近距离之和。
解题分析:
删除操作不好实现,逆向思维,从后往前添加点。然后就是利用floyd进行离线处理……感觉对floyd还是理解的不够深刻。
#include <bits/stdc++.h> using namespace std; const int N = 505; #define pb push_back #define REP(i,s,t) for(int i=s;i<=t;i++) typedef long long ll; ll f[N][N],ans[N]; int n,del[N]; inline void floyd(){ REP(k,1,n){ int K=del[k]; REP(i,1,n){ int I=del[i]; REP(j,1,n){ int J=del[j]; f[I][J]=min(f[I][J],f[I][K]+f[K][J]); if(i<=k&&j<=k) ans[k]+=f[I][J]; } } } } int main(){ cin>>n; REP(i,1,n) REP(j,1,n){ cin>>f[i][j]; } for(int i=n;i>=1;i--)cin>>del[i]; floyd(); for(int i=n;i>=1;i--)cout<<ans[i]<<" "; }