Codeforces 296D Greg And Graph (逆向处理)Floyd

来源:互联网 发布:mac怎么使用百度云 编辑:程序博客网 时间:2024/05/17 05:58

点击打开链接

题意:n个点的有向带权完全图,第i次删除一个点及其所有的边,
n<=500,求删除xi之前,任意两点最短距离的累加和,  ? 



逆着考虑:相当于每次添加一个结点后,在更新最短路径.O(n^3)

对第m个新加入的点x,n^2更新x(出发/结尾)时中间点编号为后m+1个的d^(m+1)值 在n^2更更新中间点为x时的d^m值即可.

#include <bits/stdc++.h>using namespace std;typedef long long ll;const double eps=1e-10;const int inf=0x3f3f3f3f;const int N=5e2+20;ll g[N][N],d[N][N],n,a[N];vector<ll> ans;void solve(){ans.clear();ans.push_back(0);int m=1;while(m<n){ll res=0;for(int k=n-m;k<=n;k++){for(int i=n-m;i<=n;i++){int u=a[k],v=a[i],x=a[n-m];d[x][v]=min(d[x][v],d[x][u]+d[u][v]);d[v][x]=min(d[v][x],d[v][u]+d[u][x]);}}for(int i=n-m;i<=n;i++){for(int j=n-m;j<=n;j++){int u=a[i],v=a[j],x=a[n-m];d[u][v]=min(d[u][v],d[u][x]+d[x][v]);res+=d[u][v];}}m++;ans.push_back(res);}for(int i=ans.size()-1;i>=0;i--)printf("%I64d ",ans[i]);printf("\n");}int main(){while(cin>>n){for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%I64d",&d[i][j]);for(int i=1;i<=n;i++)scanf("%I64d",&a[i]);solve();}return 0;}










原创粉丝点击