对于这道题肯定是要求最短路的应为他涉及到了最长路,我们可以设 d[i][j]表示 i 到 j 的最短距离。
假设最远点在边(i,j)上。设最远点到 i 的距离是 x。
最远点到所有点的距离和就是
∑
k
=
1
n
\sum_{k=1}^{n}
∑k=1nmin(x+d[i][k],w[i][j]-x+d[j][k])
就是首先这个最远点到i,i还要到其他点,就要加上d[i][k],但也可能直接从最远点到这个点
就是判断a+b和c
转换一下就是
把sigma展开得
第一项与我们的x不相关,所以关心第二项就可以了
代码中的最短路用的是floyd(13,14,15,16行)
当时想的是暴力枚举最远点和其他所有顶点依次存下来相加复杂度( n 5 n^5 n5)过不了(逃
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m,x,k,l,r,ans=1<<30,g[305][305],d[305][305],a[305];
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;g[i][j++]<<=1)
scanf("%d",&g[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=g[i][j]<<1;
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
for(int k=1;k<=n;k++)
a[k]=d[j][k]+g[i][j]-d[i][k]>>1;
nth_element(a+1,a+(n+1>>1),a+n+1);
l=a[n+1>>1];
nth_element(a+1,a+(n>>1)+1,a+n+1);
r=a[(n>>1)+1];
if(max(l,0)<=min(r,g[i][j]))
m=max(l,0);
else if(l>g[i][j])
m=g[i][j];
else
m=0;
for(k=1,x=0;k<=n;k++)
x+=min(d[i][k]+m,g[i][j]-m+d[j][k]);
ans=min(ans,x);
}
}
printf("%d.%d000\n",ans>>1,(ans&1)*5);
return 0;
}