Luogu P1522 牛的旅行 Cow Tours___floyd

16 篇文章 0 订阅
15 篇文章 1 订阅

题目大意:

农场中有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;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值