这道题最值得注意的是牧场数>=2...也就是说把两个联通图相连后得到的新牧场大小并不一定是最大的..可能还有另外一个没连的直径更长...
其他的..用并查集来判断是否在一个联通图里..用Floyd求两点的最短路径~~
进入第三章了~~
Program:
/*
ID: zzyzzy12
LANG: C++
TASK: cowtour
*/
#include<iostream>
#include<istream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stack>
#include<algorithm>
#include<queue>
#define oo 2000000000
using namespace std;
struct node
{
int y,x;
}point[155];
double p[155][155],ans,ans2,sum[155];
int n,father[155];
bool getdata()
{
char c=' ';
while (c!='1' && c!='0') c=getchar();
if (c=='1') return true;
return false;
}
double dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int getfather(int i)
{
if (father[i]==i) return i;
return father[i]=getfather(father[i]);
}
void Floyd()
{
int k,i,j;
for (k=1;k<=n;k++)
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (p[i][j]>p[i][k]+p[k][j])
p[i][j]=p[i][k]+p[k][j];
return;
}
int main()
{
freopen("cowtour.in","r",stdin);
freopen("cowtour.out","w",stdout);
scanf("%d",&n);
int i,j,k;
for (i=1;i<=n;i++)
{
scanf("%d%d",&point[i].x,&point[i].y);
p[i][i]=0;
father[i]=i;
}
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (getdata())
{
p[i][j]=dis(point[i],point[j]);
father[getfather(i)]=getfather(j);
}
else if (i!=j) p[i][j]=oo;
Floyd();
memset(sum,0,sizeof(sum));
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (getfather(i)==getfather(j) && p[i][j]>sum[i])
sum[i]=p[i][j];
ans2=0;
for (i=1;i<=n;i++)
if (ans2<sum[i]) ans2=sum[i];
ans=oo;
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
if (father[i]!=father[j] && ans>sum[i]+sum[j]+dis(point[i],point[j]))
ans=sum[i]+sum[j]+dis(point[i],point[j]);
if (ans2>ans) ans=ans2;
printf("%.6lf\n",ans);
return 0;
}