UVa 10075 - Airlines

航线算球面距离,需要经纬度转空间坐标。

任意两点间距离用Floyd求出来,查询时直接查表。

 

  1 #include <cstdio>
  2 #include <map>
  3 #include <cmath>
  4 #include <string>
  5 #include <cstring>
  6 #include <cstdlib>
  7 
  8 using namespace std;
  9 
 10 const int MAXN = 110;
 11 const double INF = 1e30;
 12 const double eps = 1e-8;
 13 const double PI = acos( -1.0 );
 14 
 15 struct Point
 16 {
 17     double x, y;
 18     Point( int x = 0, int y = 0 ): x(x), y(y) {}
 19 };
 20 
 21 struct Coordinate   //空间坐标
 22 {
 23     double x, y, z;
 24 };
 25 
 26 double dist[MAXN][MAXN];
 27 Coordinate C[MAXN];
 28 
 29 double Cha( double a, double b )
 30 {
 31     return (a - b)*(a - b);
 32 }
 33 
 34 double GetDis( Coordinate a, Coordinate b )   //三维空间直线距离
 35 {
 36     return sqrt( Cha( a.x, b.x ) + Cha( a.y, b.y ) + Cha( a.z, b.z ) );
 37 }
 38 
 39 double toRad( double deg )    //角度转弧度
 40 {
 41     return deg / 180.0 * acos( -1.0 );
 42 }
 43 
 44 void get_coord( double R, double lat, double lng, double &x, double &y, double &z ) //经纬度转空间坐标
 45 {
 46     lat = toRad(lat);
 47     lng = toRad(lng);
 48     x = R*cos(lat)*cos(lng);
 49     y = R*cos(lat)*sin(lng);
 50     z = R*sin(lat);
 51     return;
 52 }
 53 
 54 void Floyd( int n )    //弗洛伊德算任意两点最短路
 55 {
 56     for ( int k = 0; k < n; ++k )
 57         for ( int i = 0; i < n; ++i )
 58         for ( int j = 0; j < n; ++j )
 59         {
 60             double temp = dist[i][k] + dist[k][j];
 61             if ( temp < dist[i][j] ) dist[i][j] = temp;
 62         }
 63     return;
 64 }
 65 
 66 int main()
 67 {
 68     int n, m, Q;
 69     double r = 6378;
 70     int cas = 0;
 71     bool flag = false;
 72     while ( scanf( "%d%d%d", &n, &m, &Q ), n || m || Q )
 73     {
 74         map<string, int> Map;
 75         for ( int i = 0; i < n; ++i )
 76         {
 77             char str[100];
 78             Point P;
 79             scanf("%s%lf%lf", str, &P.x, &P.y );
 80             get_coord( r, P.x, P.y, C[i].x, C[i].y, C[i].z );
 81             Map[ str ] = i;
 82         }
 83 
 84         for ( int i = 0; i <= n; ++i )
 85         for ( int j = 0; j <= n; ++j )
 86             dist[i][j] = INF;
 87 
 88         for ( int i = 0; i < m; ++i )
 89         {
 90             char str1[100], str2[100];
 91             scanf( "%s%s", str1, str2 );
 92             int u = Map[ str1 ];
 93             int v = Map[ str2 ];
 94             dist[u][v] = (int)( 2.0 * asin( GetDis( C[u], C[v] ) / ( 2.0 * r ) ) * r + 0.5 );  //四舍五入
 95         }
 96 
 97         Floyd( n );
 98 
 99         if ( flag ) puts("");
100 
101         printf( "Case #%d\n", ++cas );
102 
103         while ( Q-- )
104         {
105             char str1[100], str2[100];
106             scanf( "%s%s", str1, str2 );
107             int u = Map[ str1 ];
108             int v = Map[ str2 ];
109             if ( dist[u][v] >= INF - eps ) puts( "no route exists" );
110             else printf( "%.0f km\n", dist[u][v] );
111         }
112 
113         flag = true;
114     }
115     return 0;
116 }

 

posted @ 2013-06-20 00:12  冰鸮  阅读(274)  评论(0编辑  收藏  举报