题目大意
给了一个 n(1≤n≤500) 个点的有向完全图,以及邻接矩阵,现在每次删掉一个点,并问删掉这个点之后,总共删 n 次。没删掉一个点,都要求出剩余图中,所有顶点之间的最短路的和是多少,并输出
做法分析
倒着做,一个一个的加点,充分运用 Floyd 的动态规划意义
当然了,离不了 map 来哈希一下
比赛的时候算错数据范围,结果超 int 挂 ST 了,悲剧
那几天一直状态不好,跌到 div2 后迟迟不能涨回去,每场 div2 的比赛,在ST之前都是房间第一,可就是要挂 ST,总结原因,总是有些小细节没处理好,竟然没人 cha,太不科学了
参考代码

1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <map> 5 6 using namespace std; 7 8 typedef long long LL; 9 const int N=506; 10 11 LL g[N][N], dis[N][N], ans[N]; 12 int n; 13 map <int, int> ihash; 14 15 int main() 16 { 17 scanf("%d", &n); 18 for(int i=1; i<=n; i++) 19 for(int j=1; j<=n; j++) 20 scanf("%I64d", &g[i][j]); 21 ihash.clear(); 22 for(int i=1; i<=n; i++) 23 { 24 int a; 25 scanf("%d", &a); 26 ihash.insert(make_pair(a, n+1-i)); 27 } 28 29 for(int i=1; i<=n; i++) 30 for(int j=1; j<=n; j++) 31 dis[ihash[i]][ihash[j]]=g[i][j]; 32 33 memset(ans, 0, sizeof ans); 34 for(int k=1; k<=n; k++) 35 { 36 for(int i=1; i<=n; i++) 37 for(int j=1; j<=n; j++) 38 dis[i][j]=min(dis[i][j], dis[i][k]+dis[k][j]); 39 40 for(int i=1; i<=k; i++) 41 for(int j=1; j<=k; j++) 42 ans[n+1-k]+=dis[i][j]; 43 } 44 for(int i=1; i<=n; i++) 45 { 46 printf("%I64d", ans[i]); 47 if(i==n) printf("\n"); 48 else printf(" "); 49 } 50 return 0; 51 }