Title
大意:询问不经过 k ∈ [ 1 , n ] k\in [1,n] k∈[1,n],任意有序数对 ( l , k , r ) (l,k,r) (l,k,r)的最短路和。
Solution
Code
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define ll long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
using namespace std;
const int N=400,INF=0x3f3f3f3f;
int n,a[30][N][N]; ll ans;
int read(){
int p=0,f=1;char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
while (isdigit(c)) p=(p<<3)+(p<<1)+c-48,c=getchar();
return p*f;
}
void solve(int l,int r,int dep){
if (l==r){
rep(i,1,n) rep(j,1,n) if (i!=l&&j!=l) if (a[dep][i][j]<INF) ans+=a[dep][i][j]; else ans+=-1;
return;
}
memcpy(a[dep+1],a[dep],sizeof(a[dep]));
int mid=(l+r)>>1;
rep(k,l,mid) rep(i,1,n) rep(j,1,n) if (i!=k&&i!=j&&j!=k) a[dep+1][i][j]=min(a[dep+1][i][j],a[dep+1][i][k]+a[dep+1][k][j]);
solve(mid+1,r,dep+1);
memcpy(a[dep+1],a[dep],sizeof(a[dep]));
rep(k,mid+1,r) rep(i,1,n) rep(j,1,n) if (i!=k&&i!=j&&j!=k) a[dep+1][i][j]=min(a[dep+1][i][j],a[dep+1][i][k]+a[dep+1][k][j]);
solve(l,mid,dep+1);
}
int main(){
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
n=read();
rep(i,1,n) rep(j,1,n){
int x=read();
if (x!=-1) a[0][i][j]=x; else a[0][i][j]=INF;
}
solve(1,n,0);
printf("%lld",ans);
return 0;
}