1. 程式人生 > >【CodeForces - 296D】Greg and Graph(floyd)

【CodeForces - 296D】Greg and Graph(floyd)

body efi clu long 循環 一次 暴力 矩陣 最短距離

Description

題意:給定一個有向圖,一共有N個點,給鄰接矩陣。依次去掉N個節點,每一次去掉一個節點的同時,將其直接與當前節點相連的邊和當前節點連出的邊都需要去除,輸出N個數,表示去掉當前節點之前的所有兩點間最短距離和。n<=500

Solution

如果暴力打肯定是會超時的,那就要運用到floyd(hj)

floyd算法內2個循環就相當於新加入外循環的那個點然後跟新最短路,

所以可以把題目看成倒過來依次加點,每次\(n^2\)平方更新一下,總共\(O(n^3)\)

Code

#include <cstdio>
#include <algorithm>
#define ll long long
#define N 510 using namespace std; ll Ans[N],g[N][N]; int p[N],n; bool vis[N]; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i)for(int j=1;j<=n;++j)scanf("%lld",&g[i][j]); for(int i=1;i<=n;++i)scanf("%d",&p[i]); for(int i=n,now;i>=1
;--i){ vis[now=p[i]]=1; for(int j=1;j<=n;++j) for(int k=1;k<=n;++k) g[j][k]=min(g[j][k],g[j][now]+g[now][k]); for(int j=1;j<=n;++j) for(int k=1;k<=n;++k) if(vis[j]&&vis[k]) Ans[i]+=g[j][k]; } for
(int i=1;i<=n;++i) printf("%lld ",Ans[i]); return 0; }

【CodeForces - 296D】Greg and Graph(floyd)