航线算球面距离,需要经纬度转空间坐标。
任意两点间距离用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 ", ++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 ", dist[u][v] ); 111 } 112 113 flag = true; 114 } 115 return 0; 116 }