UVa10075 - Airlines(所有点对之间的最短距离)

A leading airlines company hashired you to write a program that answers the following query: given a list ofcity locations (latitudes and longitudes) and a list of direct flights what isthe minimum distance a passenger needs to fly to get from a given city toanother?

 

To get from a city to another apassenger may either take a direct flight (if exists) or take a sequence ofconnecting flights (if there exists such a route).

 

Assume that if a passenger takesa direct flight from X toY he never flies morethan the geographical distance betweenX andY.  The geographical distance between twolocationsX andY is the length of the geodetic linesegment connectingX andY. The geodetic line segment betweentwo points on a sphere is the shortest connecting curve lying entirely in thesurface of the sphere. Assume that the Earth is a perfect sphere with a radiusof exactly 6378-km and the value of p is approximately 3.141592653589793.Round the geographical distance between every pair of cities to the nearestinteger.

 

Input

The input may contain multipletest cases.

 

The first line of each test casecontains three integers N (N <= 100),M (M <= 300) andQ (Q <= 10000) whereN indicates the number of cities,M represents the number of directflights andQ is the number of queries.

 

The next N lines contain the city list. The i-th of theseN lineswill contain a stringcifollowed by two real numbersltiandlni, representing thecity name, its latitude and longitude respectively. The city name will be nolonger than 20 characters and will not contain white-space characters. Thelatitude will be between -90 (South Pole) and +90 (North Pole). The longitudewill be between -180 and +180 where negative numbers denote locations west ofthe meridian and positive numbers denote locations east of the meridian. (Themeridian passes through Greenwich, London.)

 

The next M lines contain the direct flight list. The i-th of these M lineswill contain two city names aiand bi indicating thatthere exists a direct flight from cityaito citybi. Be assuredthat both city names will occur in the city list.

 

The next Q lines contain the query list. The i-th of theseQ lineswill contain two city namesaiandbi asking for theminimum distance a passenger needs to fly in order to get from cityai to citybi. Be assured thatai  bi are not equal and both city names will occur inthe city list.

 

The input will terminate withthree zeros form N, M andQ.

 

Output

For each test case in the inputfirst output the test case number (starting from 1) as shown in the sampleoutput. Then for each query in the input print a line giving the shortestdistance (in km) a passenger needs to fly to get from the first city (ai) in the query to thesecond one (bi). If thereexists no route formaitobi, just print theline "no route exists".

Print a blankline between two consecutive test cases.

 

Sample Input

3 4 2
Dhaka 23.8500 90.4000
Chittagong 22.2500 91.8333
Calcutta 22.5333 88.3667
Dhaka Calcutta
Calcutta Dhaka
Dhaka Chittagong
Chittagong Dhaka
Chittagong Calcutta
Dhaka Chittagong
5 6 3
Baghdad 33.2333 44.3667
Dhaka 23.8500 90.4000
Frankfurt 50.0330 8.5670
Hong_Kong 21.7500 115.0000
Tokyo 35.6833 139.7333
Baghdad Dhaka
Dhaka Frankfurt
Tokyo Hong_Kong
Hong_Kong Dhaka
Baghdad Tokyo
Frankfurt Tokyo
Dhaka Hong_Kong
Frankfurt Baghdad
Baghdad Frankfurt
0 0 0

Sample Output

Case #1
485 km
231 km

Case #2
19654 km
no route exists
12023 km

1、地理坐标系下两个已知点的距离的求法

纬度用alpha,经度用belta表示,都是用弧度来表示的,R表示球体的半径,则对应的坐标表示为

x=R * cos(alpha)*cos(belta),   y = R*cos(alpha)*sin(belta), z = R * sin(alpha)

已知两个点的坐标后A(x1, y1, z1),B(x2, y2, z2),则两个半径的夹角(用theta表示)关系式为:

cos(theta) = (x1 * x2 + y1 * y2 + z1 * z1) / (R * R)

AB两点的地理距离为d = PI * theta

2、用floyd_warshell求所有点对之间的最短距离

#include <cstdio>
#include <map>
#include <string>
#include <cmath>
#include <algorithm>

using namespace std;

const int N = 110, INF = 0x3f3f3f3f;
const int STRLEN = 25;
const double PI = acos(-1);
const int R = 6378;

struct Location
{
    double lati, longti;
};

Location location[N];
int f[N][N];
int n, m, q;
map<string, int> strMap;
int t;

bool input();
void solve();
int dis(int a, int b);

int main()
{
#ifndef ONLINE_JUDGE
    freopen("d:\\OJ\\uva_in.txt", "r", stdin);
#endif // ONLINE_JUDGE

    t = 1;
    while (input()) {
        solve();
    }
    return 0;
}

bool input()
{
    strMap.clear();
    scanf("%d%d%d", &n, &m, &q);

    if (n == 0 && m == 0 && q == 0) return false;

    char buf[STRLEN];

    for (int i = 0; i < n; i++) {
        scanf("%s%lf%lf", buf, &location[i].lati, &location[i].longti);
        string str = buf;
        strMap[str] = i;
    }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i == j) f[i][j] = 0;
            else f[i][j] = INF;
        }
    }
    for (int i = 0; i < m; i++) {
        scanf("%s", buf);
        string s = buf;
        int u = strMap[s];

        scanf("%s", buf);
        s = buf;
        int v = strMap[s];

        f[u][v] = dis(u, v);
    }

    return true;
}

int dis(int a, int b)
{
    double alpha = location[a].lati / 180 * PI;
    double belta = location[a].longti / 180 * PI;

    double z1 = R * sin(alpha);
    double x1 = R * cos(alpha) * cos(belta);
    double y1 = R * cos(alpha) * sin(belta);

    alpha = location[b].lati / 180 * PI;
    belta = location[b].longti / 180 * PI;
    double z2 = R * sin(alpha);
    double x2 = R * cos(alpha) * cos(belta);
    double y2 = R * cos(alpha) * sin(belta);

    double theta = acos((x1 * x2 + y1 * y2 + z1 * z2) / R / R);

    return (int)round(R * theta);
}

void solve()
{
    for (int k = 0; k < n; k++) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (f[i][k] != INF && f[k][j] != INF) {
                    f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
                }
            }
        }
    }

    if (t > 1) printf("\n");
    printf("Case #%d\n", t++);
    for (int i = 0; i < q; i++) {
        char buf1[STRLEN], buf2[STRLEN];
        scanf("%s%s", buf1, buf2);
        string s1 = buf1, s2 = buf2;
        int u = strMap[s1], v = strMap[s2];
        if (f[u][v] != INF) {
            printf("%d km\n", f[u][v]);
        } else {
            printf("no route exists\n");
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值