先用Floyd求一次最短路,然后记录对于每一个点距离最远的点,枚举任意两个不联通的点将它们联通,计算新的牧场直径(两点间的距离加上他们各自的最远距离)。
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
const double INF=1e9*1.0;
int n;
int x[160],y[160];
double a[160][160],d[160],l1,l2=INF,ans;
double dis(int i,int j)
{
return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d %d",&x[i],&y[i]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
int t;
scanf("%1d",&t);
if(t) a[i][j]=dis(i,j);
else if(i!=j) a[i][j]=INF;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
if(i!=k) for(int j=1;j<=n;j++)
if(i!=j && k!=j && a[i][k]+a[k][j]<a[i][j]) a[i][j]=a[i][k]+a[k][j];
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
if(a[i][j]!=INF) d[i]=max(d[i],a[i][j]);
l1=max(l1,d[i]);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(a[i][j]==INF) l2=min(l2,d[i]+d[j]+dis(i,j));
ans=max(l1,l2);
printf("%.6f",ans);
}