# Codeforces Round #179 (Div. 2)D. Greg and Graph【floyd变形】

http://codeforces.com/contest/296/problem/D

Floyd—Warshall算法的原理是动态规划。

（1）若最短路径经过点k，那么D[i][j][k]=D[i][k][k-1]+D[k][j][k-1]

（2）若最短路径不经过点k，那么D[i][j][k]=D[i][j][k-1]

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <queue>
using namespace std;
template <class T> void checkmin(T &t,T x) {if(x < t) t = x;}
template <class T> void checkmax(T &t,T x) {if(x > t) t = x;}
template <class T> void _checkmin(T &t,T x) {if(t==-1) t = x; if(x < t) t = x;}
template <class T> void _checkmax(T &t,T x) {if(t==-1) t = x; if(x > t) t = x;}
typedef pair <int,int> PII;
typedef pair <double,double> PDD;
typedef long long ll;
#define foreach(it,v) for(__typeof((v).begin()) it = (v).begin(); it != (v).end ; it ++)
int n ;
const int N = 555;
int g[N][N];
ll ans[N];
int a[N];
int main() {
cin >> n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) cin >> g[i][j];
for(int i=n;i>=1;i--) cin >> a[i];
ans[1] = 0;
for(int i=2;i<=n;i++) {
int aa = a[i];
ans[i] += ans[i-1];
for(int j=1;j<i;j++)
ans[i] += g[a[i]][a[j]] + g[a[j]][a[i]];
for(int j=1;j<i;j++)
for(int k=1;k<i;k++) {
if(g[a[j]][a[i]] > g[a[j]][a[k]]+g[a[k]][a[i]]) {
ans[i] -= g[a[j]][a[i]];
ans[i] += g[a[j]][a[k]]+g[a[k]][a[i]];
g[a[j]][a[i]] = g[a[j]][a[k]]+g[a[k]][a[i]];
}
if(g[a[i]][a[j]] > g[a[i]][a[k]] + g[a[k]][a[j]]) {
ans[i] -= g[a[i]][a[j]];
ans[i] += g[a[i]][a[k]] + g[a[k]][a[j]];
g[a[i]][a[j]] = g[a[i]][a[k]] + g[a[k]][a[j]];
}
}
for(int j=1;j<i;j++)
for(int k=1;k<i;k++) {
if(g[a[j]][a[k]] > g[a[j]][a[i]] + g[a[i]][a[k]]) {
ans[i] -= g[a[j]][a[k]];
ans[i] += g[a[j]][a[i]] + g[a[i]][a[k]];
g[a[j]][a[k]] = g[a[j]][a[i]] + g[a[i]][a[k]];
}
}
}
cout << ans[n];
for(int i=n-1;i>=1;i--) cout << " "<< ans[i];
cout << endl;
return 0;
}

posted @ 2013-04-12 03:16  aiiYuu  阅读(424)  评论(2编辑  收藏  举报