这道题主要是看对floyd算法的理解程度,还有就是正面不好推,就反过来推。
#include<bits/stdc++.h>
using namespace std;
#define clr(a,b) memset(a,b,sizeof(a))
#define pb(a) push_back(a)
#define fir first
#define se second
#define LL long long
typedef pair<int,int> pii;
typedef pair<int,LL> pil;
const double eps = 0.0000001;
const LL inf = 0x3f3f3f3f3f3f3f;
const int maxn = 1e5+5;
LL dis[505][505],ans[505],num[505];
int main() {
int n;
scanf("%d",&n);
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
scanf("%I64d",&dis[i][j]);
for(int i = 1;i <= n;i++) scanf("%I64d",&num[i]);
int cnt = 0;
for(int k = n;k >= 1;k--) {
for(int i = 1;i <= n;i++)
for(int j = 1;j <= n;j++)
if(dis[i][num[k]] + dis[num[k]][j] < dis[i][j]) //把floyd算法每一步的答案输出,就是题目的答案,也算图的一种dp
dis[i][j] = dis[i][num[k]] + dis[num[k]][j];
LL sum = 0;
for(int i = n;i >= k;i--)
for(int j = n;j >= k;j--)
sum += dis[num[i]][num[j]];
ans[++cnt] = sum;
}
for(int i = n;i >= 1;i--) printf("%I64d ",ans[i]);
printf("\n");
}