TOJ-1336 Airline Hub

本文探讨了一种算法,用于确定全球范围内能最优化连接多个机场的中央枢纽位置。通过将机场间的距离排序并遍历,可以找到使得最大直接飞行距离最小化的机场作为理想枢纽。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

World Wide Flyer has landing rights at several airports throughout the world. They wish to place their central hub at the airport that minimizes the maximum direct flying distance from the hub to any other airport in the world.

Input consists of a line containing n ≤ 1000, the number of airports. n lines follow, each giving the latitude (between -90 and +90 degrees) and longitude (between -180 and +180 degrees) of an airport.

To two decimal places, give the latitude and longitude of the airport that best serves as a hub. If there are several any one will do.

Sample Input

3
3.2 -15.0
20.1 -175
-30.2 10

Output for Sample Input

3.20 -15.00



Source: Waterloo Local Contest Jan. 29, 2000

题目要求一机场坐标,该机场到其他各机场的距离的最大值是所有机场中最小的。

将所有机场构成的边按从长到短排序,从最长边开始遍历顶点,第n个顶点纪委所求点。

这是因为排在前面的边是各个顶点到其他顶点的边中距离最大的几个,当遍历到第n个顶点时,其余顶点的最长边都已遍历过,

即该点的最长边是所有顶点的最长边中最小的。

这道题按理来说应该求球面距离,但是按直线距离求也能AC(没错,飞机从地下飞)。

以下代码摘自http://blog.youkuaiyun.com/code_or_code/article/details/38877305

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
bool vis[1000];
double x[1000],y[1000];
int n;
int cnt;
struct node{
    int u,v;
    double dis;
}edge[500000];

int cmp(node a,node b)
{
    return a.dis>b.dis;
}


void cul(int u,int v)
{
    edge[cnt].u=u;
    edge[cnt].v=v;
    double l1=x[u],d1=y[u],l2=x[v],d2=y[v];
    double p = acos(-1.0);
    l1 *= p/180.0; d1 *= p/180.0;
    l2 *= p/180.0; d2 *= p/180.0;
    edge[cnt].dis=acos(cos(l1)*cos(l2)*cos(d1-d2)+sin(l1)*sin(l2));
    cnt++;
}

int main()
{
    memset(vis,true,sizeof vis);
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%lf%lf",&x[i],&y[i]);

    cnt=0;
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
        {
            cul(i,j);
        }
    sort(edge,edge+cnt,cmp);
    int num=0;
    for(int i=0;i<cnt;i++)
    {
        if(vis[edge[i].u])
        {
            num++;
            vis[edge[i].u]=false;
        }
        if(num==n-1) break;
        if(vis[edge[i].v])
        {
            num++;
            vis[edge[i].v]=false;
        }
        if(num==n-1) break;
    }
    for(int i=0;i<n;i++)
        if(vis[i]){
            printf("%.2lf %.2lf\n",x[i],y[i]);
            break;
        }

    return 0;
}

这道题的数据还有另一个问题,就是所有测试数据的答案都是到(0,0)点最近的点(这显然不对)。。。这是POJ的discuss版块中发现的,

发现者用以下代码AC了。。。

#include<stdio.h>
int main()
{
    double a,b,x,y,m=99999;
    int n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%lf%lf",&a,&b);
        if(m>a*a+b*b)
        {
            m=a*a+b*b;
            x=a;
            y=b;
        }
    }
    printf("%.2lf %.2lf\n",x,y);
    return 0;
}

我也不知道为什么会生成这样的测试数据。。。

转载于:https://www.cnblogs.com/shenchuguimo/p/6366219.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值