UVA - 10075(几何+floyd)

给出每个点的经纬,和航线(有向边),求最短路

题意很简单,主要是距离的转化,先把经纬度转化成弧度数,然后转化出每个点的(x,y,z) 然后在球上求距离。

#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <cmath>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#define INF  0x3f3f3f3f
using namespace std;
int n, m,q ;
const double PI = 3.141592653589793;
const double r = 6378 ;
const int maxn = 10000+10;
struct Point
{
    double lt,ln;
    double ht,hn;
    string name;
    double x,y,z;
} s[maxn];
map<string,int>ma;
int E;
int g[200][200];
int get_id(string s1)
{
    if(ma[s1])
    {
        return ma[s1];
    }
    else
    {
        E++;
        ma[s1] = E;
        return E;
    }
}
int get_dis(int i,int j)
{
    double l = acos((s[i].x * s[j].x + s[i].y * s[j].y  + s[i].z * s[j].z ) / (r*r));
    l = round(l * r);
    
    return l;
}
void get_pos(int i)
{
    double l = r * cos(s[i].ht);
    s[i].x = l * cos(s[i].hn);
    s[i].z = r * sin(s[i].ht);
    s[i].y = l * sin(s[i].hn);
//    cout << "*******" << endl;
//    printf("%lf %lf %dlf\n",s[i].x,s[i].y,s[i].z);
//    cout << "*******" << endl;
}
void floyd()
{
    for(int k = 1 ; k <= E ; k++)
    {
        for(int i = 1 ; i <= E ; i++)
        {
            for(int j = 1 ; j <= E ; j++)
            {
                if(g[k][j] != INF && g[i][k] != INF)
                    g[i][j] = min(g[i][j],g[i][k] + g[k][j]);
            }
        }
    }
}
int main()
{
    int kase = 1;
    while(cin >> n >> m >> q && (n||m||q))
    {
        E = 0;
        ma.clear();
        memset(g,0,sizeof(g));
        for(int i = 0 ; i < n ; i++)
        {
            cin >> s[i].name;
            scanf("%lf%lf",&s[i].lt,&s[i].ln);
            s[i].ht = s[i].lt * PI / 180;
            s[i].hn = s[i].ln * PI / 180;
            get_pos(i);
        }

        for(int i = 0 ; i <= n ; i++)
        {
            for(int j = 0 ; j <= n ; j++)
            {
                if(i!=j)
                {
                    g[i][j] = INF;
                }
            }
        }
//        for(int i = 0 ; i < n ; i++)
//        {
//            for(int j = 0 ; j < n ;j++)
//            {
                int from =
//                if(i!=j)
//                {
//                    g[get_id(s[i].name)][get_id(s[j].name)] = get_dis(i,j);
//                }
//            }
//        }
        string s1,s2;
        for(int i = 0 ; i< m ; i++)
        {
            cin >> s1 >> s2;
            int x1 = get_id(s1);
            int x2 = get_id(s2);
            bool flag = false;
            for(int j = 0; j < n ; j++)
            {
                for(int k = 0 ; k < n ; k++)
                {
                    if(s[j].name == s1 && s[k].name == s2)
                    {
                        g[x1][x2] = get_dis(j,k);
//                        cout << "get:" << get_dis(j,k) << endl;
                        flag=true;
                        break;
                    }
                }
                if(flag) break;
            }
        }
        floyd();
//        cout << "E : " << endl;
//        for(int k = 1 ; k <= E ; k++)
//        {
//            for(int i = 1 ; i <= E ; i++)
//            {
//                g[i][j] = min(g[i][j],g[i][k] + g[k][j]);
//                }
//            }
//        }
        if(kase > 1) cout <<endl;
        printf("Case #%d\n",kase++);
        for(int i = 0 ; i< q ; i++)
        {
            cin >> s1 >> s2;
            int x1 = get_id(s1);
            int x2 = get_id(s2);
//            cout << "xxxx" << x1 << " " << x2 << endl;
//            for(int k = 1 ; k <= E ; k++)
//        {
//            for(int i = 1 ; i <= E ; i++)
//            {
//
            if(g[x1][x2] != INF)
            {
                printf("%d km\n",g[x1][x2]);
            }
            else
            {
                printf("no route exists\n");
            }
        }
//        if()
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值