AcWing 1125. 牛的旅行
原题链接
简单
作者:
shenbc
,
2021-04-04 20:14:59
,
所有人可见
,
阅读 269
#include<iostream>
#include<cmath>
using namespace std;
const int N=160,MAX=0x3f3f3f3f;
struct Pos{
int x,y;
};
double dis[N][N];
int n;
Pos pos[N];
double maxdis[N];//到第i个点的最远的点的距离
double cal(int x1,int y1,int x2,int y2){
return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
}
void floyd(){
for(int t=1;t<=n;t++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dis[i][j]>dis[i][t]+dis[t][j]){
dis[i][j]=dis[i][t]+dis[t][j];
}
}
}
}
return;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int x,y;
cin>>pos[i].x>>pos[i].y;
}
getchar();
int c;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
c=getchar()-'0';
if(i==j)continue;//注意ij相等
if(c==1){
dis[i][j]=cal(pos[i].x,pos[i].y,pos[j].x,pos[j].y);
}else{
dis[i][j]=MAX;
}
}
getchar();
}
floyd();
/*for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cout<<dis[i][j]<<"\t";
}
cout<<endl;
}*/
double ans1=0,ans2=MAX;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dis[i][j]!=MAX){//浮点数不应该直接比较相等
maxdis[i]=max(maxdis[i],dis[i][j]);
}
ans1=max(ans1,maxdis[i]);
}
}
//for(int i=1;i<=n;i++)cout<<maxdis[i]<<endl;
//枚举每一对不连通的点对,考虑在这两个点加边.
//加完边后,我们注意到此时的直径应该是
//maxdis[i]+dis(i,j)+maxdis[j]
//找maxdis最小即可
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dis[i][j]==MAX){
double tmplen=cal(pos[i].x,pos[i].y,pos[j].x,pos[j].y);
ans2=min(ans2,maxdis[i]+tmplen+maxdis[j]);
}
}
}
printf("%.6lf",max(ans1,ans2));
return 0;
}