1. 程式人生 > >洛谷P1027 Car的旅行路線 計算幾何 圖論最短路

洛谷P1027 Car的旅行路線 計算幾何 圖論最短路

name ani 但是 ret sqrt bsp include struct ==

題意 求某城到某城的最小花費
一個城中有四個機場,一個城中的機場相互可達,用公路到達,但是不同城的公路的單位路程的
費不同,兩個不同城的機場(我不知道相同城可不可以)可以通過機場到達,且飛機單位路程價格
一定,問從 a 城到b城的最小花費,可從a的任一機場出發,從 b 的任一機場結束 。

題解 這道題思路還算容易,就是求最短路,只是建圖比較麻煩,

總體思路
1、建圖
(1) 相同城 的四個機場兩兩連線 求距離,
【1】但是他只給出了三個點,也就是說這第四個點要我們自己求
首先他給出三個點,這三個點一定構成一個直角三角形,因為四個點構成的是矩形
【2】然後我們就可以求三角形的最長邊,最長邊即斜邊,斜邊對應的頂點即為直角頂點
【3】 然後知道直角頂點,就可以用平移法則算出第四個點的坐標了
(2) 然後任意兩個機場兩兩連線,模擬飛機到達,我不知道相同城是否可以用飛機到達,反正
我是當他可以的。
(3)這樣建圖建好了,然後跑一遍floyd 最短路就行了

註意這題邊多點少,邊是滿的,所以建議用floyd 多源最短路,不建議用 SPFA

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <cstdlib>
 5 #include <algorithm>
 6 #include <string>
 7 #include <iomanip>
 8 #include <iostream>
 9 using namespace std ;
10 
11 const
int inf = 700000000 ; 12 struct node{ 13 double x,y ; 14 }; 15 node e[101] ; 16 int n,a,b,t,tt,cnt,tz ; 17 double mi ; 18 double f[101][101],dist[101][101] ; 19 20 inline double sqr(double x) 21 { 22 return x*x; 23 } 24 25 inline void ce(int t1,int t2) // 計算兩點間的直線距離 26 { 27 double d = sqrt ( sqr(e[t1].x-e[t2].x) + sqr(e[t1].y-e[t2].y) ) ;
28 dist[t1][t2] = d ; 29 dist[t2][t1] = d ; 30 } 31 32 inline int calc(int t1,int t2,int t3) // 返回 斜邊對應的直角頂點 33 { 34 if(dist[t1][t2]>dist[t1][t3]&&dist[t1][t2]>dist[t2][t3]) return t3 ; 35 if(dist[t1][t3]>dist[t1][t2]&&dist[t1][t3]>dist[t2][t3]) return t2 ; 36 if(dist[t2][t3]>dist[t1][t3]&&dist[t2][t3]>dist[t1][t2]) return t1 ; 37 } 38 39 inline void add(int t1,int t2,int t3,int w ) // 計算四點中第四個點的坐標 40 { 41 ce(t1,t2) ; 42 ce(t2,t3) ; 43 ce(t3,t1) ; 44 int xie = calc(t1,t2,t3) ; 45 if (xie==t2) swap(t1,t2) ; 46 if (xie==t3) swap(t1,t3) ; 47 e[ w ].x = e[t2].x+e[t3].x-e[t1].x ; 48 e[ w ].y = e[t2].y+e[t3].y-e[t1].y ; 49 } 50 51 inline void pree() 52 { 53 cnt = 0 ; 54 for(int i=1;i<=100;i++) e[i].x = 0,e[i].y = 0 ; 55 56 } 57 58 int main() 59 { 60 scanf("%d",&tz) ; 61 for(int v=1;v<=tz;v++) 62 { 63 pree() ; 64 scanf("%d%d%d%d",&n,&t,&a,&b ) ; 65 for(int i=1;i<=100;i++) 66 for(int j=1;j<=100;j++) dist[ i ][ j ] = inf ; 67 for(int i=1;i<=n;i++) 68 { 69 for(int j=1;j<=3;j++) 70 ++cnt,scanf("%lf%lf",&e[cnt].x,&e[cnt].y) ; 71 ++cnt ; 72 add(cnt-3,cnt-2,cnt-1,cnt) ; 73 scanf("%d",&tt) ; 74 for(int j=cnt-3;j<=cnt-1;j++) 75 for(int k =j+1;k<=cnt;k++) 76 ce(j,k),dist[j][k]=dist[j][k]*tt,dist[k][j]=dist[k][j]*tt ; 77 } 78 for(int i=1;i<=cnt;i++) 79 for(int j=1;j<=cnt;j++) f[ i ][ j ] = dist[ i ][ j ] ; 80 for(int i=1;i<=cnt;i++) 81 for(int j=1;j<=cnt;j++) 82 { 83 ce(i,j) ; 84 if(dist[i][j]*t<f[i][j]) f[i][j] = dist[i][j]*t,f[j][i] = dist[i][j]*t ; 85 } 86 for(int k=1;k<=cnt;k++ ) 87 for(int i=1;i<=cnt;i++ ) 88 for(int j=1;j<=cnt;j++ ) 89 if(i!=j&&j!=k&&i!=k) f[i][j] = min(f[i][j],f[i][k]+f[k][j]) ; // 90 mi = 2e9 ; 91 for(int i=4*a-3;i<4*a;i++) 92 for(int j=4*b-3;j<=4*b;j++) 93 if(mi>f[i][j]) mi = f[i][j] ; 94 printf("%.1lf\n",mi) ; 95 96 } 97 return 0 ; 98 }

洛谷P1027 Car的旅行路線 計算幾何 圖論最短路