P1522 牛的旅行 (Floyed)

Posted willendless

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1522 牛的旅行 (Floyed)相关的知识,希望对你有一定的参考价值。

【题目描述】

    请编程找出一条连接两个不同牧场的路径,使得连上这条路径后,这个更大的新牧场有最小的直径。输出在所有牧场中最小的可能的直径。

【题目链接】

    https://www.luogu.org/problemnew/show/P1522

【算法】

    输出的解应当是(最大的原牧场直径)和  min(新生成的路径+新生成的路径两个端点延申出去的最长路径之和)的较大值。

    枚举所有不连通的点计算两点之间距离和它们在原牧场中延申的最长路径(用到任意两点间最短距离,floyed)之和的最小值,最后和最大原牧场直径(最大延申路径)比较即可。

    相同点间距离最好初始化为0。

【代码】

 1 #include <bits/stdc++.h>
 2 #define P pair<int,int>
 3 using namespace std;
 4 int n,i,j,k,tmp;
 5 P p[200];
 6 double d[200][200],rec[200],ans=1e12,rm;
 7 double calc(P p1,P p2)
 8 {
 9     return sqrt((p1.first-p2.first)*(p1.first-p2.first)+(p1.second-p2.second)*(p1.second-p2.second));
10 }
11 int main()
12 {
13     scanf("%d",&n);
14     for(i=1;i<=n;i++) scanf("%d%d",&p[i].first,&p[i].second);
15     for(i=1;i<=n;i++)
16         for(j=1;j<=n;j++){
17             scanf("%1d",&tmp);
18             if(tmp) d[i][j]=calc(p[i],p[j]);
19             else if(i!=j) d[i][j]=1e20;
20         }
21     for(k=1;k<=n;k++) {
22         for(i=1;i<=n;i++)
23             for(j=1;j<=n;j++)
24                 d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
25     }
26     for(i=1;i<=n;i++) {
27         for(j=1;j<=n;j++)
28             if(d[i][j]<1e7-1) rec[i]=max(rec[i],d[i][j]);
29         rm=max(rm,rec[i]);
30     }
31     for(i=1;i<=n;i++)
32         for(j=1;j<=n;j++)
33             if(d[i][j]>1e7-1) ans=min(ans,rec[i]+rec[j]+calc(p[i],p[j]));
34     ans=max(ans,rm);
35     printf("%.6f",ans);
36     return 0;
37 }

 

以上是关于P1522 牛的旅行 (Floyed)的主要内容,如果未能解决你的问题,请参考以下文章

P1522 牛的旅行 Cow Tours

Luogu P1522 牛的旅行 Cow Tours

NOIP2001T4car的旅行计划

codevs 1405 牛的旅行x

记录一个floyed的神仙方法

洛谷1522牛的旅行