Greg and Graph

题目

思路

  • 这题利用Floyd的逆操作,不断删除,倒过来就相当与不断的加入点,每次加入一个点再Floyd里面就相当于更新了这个点对于其他点最短路的影响,如果只计算已加入的点的最短路,那么此时发现已加入的点只被已加入的点更新过最短路了(有点绕),此时这些点的最短路就是只有这几个点的最短路,记录下每一次新加入点所有已加入的最短路的和即可。

代码

#include 
#include 
#include 
using namespace std;
const int N=510;
typedef long long ll;
ll d[N][N];
ll a[N];
ll ans[N];
bool vis[N];
int main(){
    int n;
    cin >> n ;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin >> d[i][j];
        }
    }
    for(int i=1;i<=n;i++){
        cin >> a[i];
    }
    for(int k=n;k>0;k--){
        int v=a[k];
        vis[v]=true;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                d[i][j]=min(d[i][j],d[i][v]+d[v][j]);
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(vis[i]&&vis[j])ans[k]+=d[i][j];
            }
        }
    }
    for(int i=1;i<=n;i++){
        cout << ans[i] << " ";
    }
}

你可能感兴趣的:(cf)