该题要求找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径,并输出那个最小可能的直径。
那么,首先根据输入的数据求出联通的牧区形成的牧场,并找出每个牧场的直径,然后用一个双重循环找出符合要求的直径即可。
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
double dis(int x1,int y1,int x2,int y2)
{
return (sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)));
}
int main()
{
freopen("cowtour.in","r",stdin);
freopen("cowtour.out","w",stdout);
int n,x[151],y[151];
char c;
double map[151][151],m[151],temp=1e20;
cin>>n;
for(int i=1;i<=n;i++)
cin>>x[i]>>y[i];
for(int i=0;i<=n;i++)
m[i]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>c;
if(i==j) map[i][j]=0;
else if(c=='1')
map[i][j]=dis(x[i],y[i],x[j],y[j]);
else map[i][j]=1e20;
}
//floyed 求出牧场
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(map[i][k]+map[k][j]<map[i][j])
map[i][j]=map[i][k]+map[k][j];
//求出牧场中相距最远的牧区之间的距离
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(map[i][j]!=1e20 && map[i][j]>m[i])
m[i]=map[i][j];
//找出符合要求的路径
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(map[i][j]==1e20)
{
if(dis(x[i],y[i],x[j],y[j])+m[i]+m[j]<temp)
temp=dis(x[i],y[i],x[j],y[j])+m[i]+m[j];
}
for(int i=1;i<=n;i++)
if(m[i]>temp)
temp=m[i];
printf("%.6lf\n",temp);
return 0;
}