用floyd预处理两个点之间的距离,用max[i]表示每个点所能到达的最长距离,用并查集判断两个点是否同属一个牧区,并求出每个点所在牧场的直径maxdis[i],枚举每两个不在同一牧区的点i,j,判断连上这两个点后的新牧场的直径max(maxdis[i],maxdis[j],max[i]+max[j]+i,j间距离是否最小

最后一定要注意的是,其他牧场的直径可能本身就比所连两个点之后的直径要大,这时应该输出最大的直径

{
ID:lucky141
PROG:cowtour
LANG:PASCAL
}
program cowtour;
type
  node=record
    x,y:integer;
  end;
var
  data:array[1..150] of node;
  max:array[1..150] of real;
  g:array[1..150,1..150] of real;
  father:array[1..150] of integer;
  i,j,k,n:integer;
  ans,x:real;
function suan(p,q:integer):real;
begin
  suan:=sqrt(sqr(data[p].x-data[q].x)+sqr(data[p].y-data[q].y));
end;
function getfather(s:integer):integer;
begin
  if father[s]=s then getfather:=s
    else
    begin
      father[s]:=getfather(father[s]);
      getfather:=father[s];
    end;
end;
procedure init;
var
  i,j,fx,fy:integer;
  s:string;
begin
  readln(n);
  for i:=1 to n do
    readln(data[i].x,data[i].y);
  for i:=1 to n do
    father[i]:=i;
  for i:=1 to n do
  begin
    readln(s);
    for j:=1 to i-1 do
      if s[j]='1' then
      begin
        fx:=getfather(i);
        fy:=getfather(j);
        if fx<>fy then father[fx]:=fy;
        g[i,j]:=suan(i,j);
        g[j,i]:=g[i,j];
      end;
  end;
end;
procedure floyd;
var
  i,j,k:integer;
begin
  for i:=1 to n do
    g[i,i]:=0;
  for k:=1 to n do
    for i:=1 to n do
      for j:=1 to n do
        if g[i,k]+g[k,j]<g[i,j] then g[i,j]:=g[i,k]+g[k,j];
end;
procedure work;
var
  max1:real;
  i,j,k:integer;
  maxdis:array[1..150] of real;
begin
  fillchar(max,sizeof(max),0);
  for i:=1 to n do
    for j:=1 to n do
      if (g[j,i]<>x) and (max[i]<g[j,i]) then max[i]:=g[j,i];
  fillchar(maxdis,sizeof(maxdis),0);
  for i:=1 to n do
    for j:=1 to n do
      if (i<>j) and (father[i]=father[j]) and (max[j]>maxdis[i]) then maxdis[i]:=max[j];
  ans:=1000000;
  for i:=1 to n-1 do
    for j:=i+1 to n do
      if father[i]<>father[j] then
      begin
        if maxdis[i]>maxdis[j] then max1:=maxdis[i]
          else max1:=maxdis[j];
        if max1<max[i]+max[j]+suan(i,j) then max1:=max[i]+max[j]+suan(i,j);
        if ans>max1 then ans:=max1;
      end;
  max1:=0;
  for i:=1 to n do
    if maxdis[i]>max1 then max1:=maxdis[i];
  if max1>ans then ans:=max1;
end;
begin
  assign(input,'cowtour.in');
  reset(input);
  assign(output,'cowtour.out');
  rewrite(output);
  fillchar(data,sizeof(data),0);
  fillchar(g,sizeof(g),$5F);
  x:=g[1,1];
  init;
  floyd;
  work;
  writeln(ans:0:6);
  close(input);
  close(output);
end.