用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.