题目大意:
农场中有N个点,给出N个点的坐标xi,yi,以及他们的连通情况,农场最大的直径为最大的两点间最短路,问任意连通一对不连通的点[i,j]后,农场最小的直径是多少。
1 <= N <= 150
0 <= X ,Y<= 100000
所求直径保留六位小数。
只需要打到小数点后六位即可,不要做任何特别的四舍五入处理。
题解:
用floyd找出两两间的最短路,注意一开始自己跟自己的距离是0,跟联通的点初值用勾股求出距离
找出每个点到其他点的最大值cmax[i]
然后当前农场的最大直径max1即为max{cmax[i]}
然后枚举不连通的i,j将i,j连通,判断
找一个min1即min{cmax[i]+cmax[j]+两点间距离(即连通花费)}
然后因为可能min1 < max1
所以找一个最大的
即ans为max{min1,max1}
代码:
#include<bits/stdc++.h>
#define INF 23333333
#define N 155
using namespace std;
struct node
{
double x,y;
}xy[N];
double f[N][N],cmax[N],max1,min1;
int n;
char x;
double rp(int r1, int r2)
{
return sqrt((xy[r1].x-xy[r2].x)*(xy[r1].x-xy[r2].x)+
(xy[r1].y-xy[r2].y)*(xy[r1].y-xy[r2].y));
}
int main()
{
cin>>n;
for (int i=1; i<=n; i++) cin>>xy[i].x>>xy[i].y;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
{
cin>>x;
if (x-'0') f[i][j]=rp(i,j);
else if (i!=j) f[i][j]=INF;
}
for (int k=1; k<=n; k++)
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
if (k!=i && k!=j && i!=j)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
max1=0;
for (int i=1; i<=n; i++)
{
for (int j=1; j<=n; j++)
if (f[i][j]!=INF) cmax[i]=max(cmax[i],f[i][j]);
max1=max(max1,cmax[i]);
}
min1=INF;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
if (f[i][j]==INF) min1=min(min1,cmax[i]+cmax[j]+rp(i,j));
double ans=max(max1,min1);
printf("%0.6f\n",ans);
return 0;
}