Vijos - Car的旅行路線(最短路)
題目描述
又到暑假了,住在城市A的Car想和朋友一起去城市B旅遊。她知道每個城市都有四個飛機場,分別位於一個矩形的四個頂點上,同一個城市中兩個機場之間有一條筆直的高速鐵路,第I個城市中高速鐵路了的單位里程價格為Ti,任意兩個不同城市的機場之間均有航線,所有航線單位里程的價格均為t。
那麼Car應如何安排到城市B的路線才能儘可能的節省花費呢?她發現這並不是一個簡單的問題,於是她來向你請教。找出一條從城市A到B的旅遊路線,出發和到達城市中的機場可以任意選取,要求總的花費最少。
輸入格式
第一行有四個正整數S,T,A,B。其中S(0<S<=100)表示城市的個數,T表示飛機單位里程的價格,A,B分別為城市A,B的序號,(1<=A,B<=S)。
接下來有S行,其中第I行均有7個正整數xi1,yi1,xi2,yi2,xi3,yi3,Ti,這當中的(xi1,yi1),(xi2,yi2),(xi3,yi3)分別是第I個城市中任意三個機場的座標,T I為第I個城市高速鐵路單位里程的價格。
輸出格式
輸出最小費用(結果保留兩位小數)
樣例輸入
3 10 1 3
1 1 1 3 3 1 30
2 5 7 4 5 2 1
8 6 8 8 11 6 3
樣例輸出
47.55
解題思路
這個就是一道最短路問題,關鍵的就是已知矩形三個點的座標,求出最後一個點的座標,只要求出這個,剩下的就好做了,這是本人寫的求法:https://blog.csdn.net/lzyws739307453/article/details/85008349
求出四個點的座標之後,題上說共有S個城市,那麼我們可以得到4*S個點(每個城市4個點),然後分別求出一個點到其餘各點的花費,城市四個點之間的按高鐵的價格算,城市與城市按飛機的價格算,跑一遍最短路,最後求出A城市的四個點分別到B城市的四個點的最小花費,求出最小值即可。
#include <queue> #include <cmath> #include <cstdio> #include <iostream> using namespace std; const double inf = 999999999; typedef struct edge { int x, y; }coor; coor e[450]; int vis[410]; double dis[410], map[410][410]; coor coordinate(coor a, coor b, coor c) { coor p; p.x = b.x + c.x - a.x; p.y = b.y + c.y - a.y; return p; } bool Judge(coor a, coor b, coor c) { if (!((b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y))) return true; return false; } void Seeking(coor a[]) { if (Judge(a[0], a[1], a[2])) a[3] = coordinate(a[0], a[1], a[2]); else if(Judge(a[1], a[0], a[2])) a[3] = coordinate(a[1], a[0], a[2]); else a[3] = coordinate(a[2], a[0], a[1]); } void Bellman_Ford(int s, int S) { queue <int> Q; for (int i = 0; i < 4 * S; i++) { vis[i] = 0; dis[i] = inf; } Q.push(s); dis[s] = 0; vis[s] = 1; while (!Q.empty()) { int u = Q.front(); Q.pop(); vis[u] = 0; for (int j = 0; j < 4 * S; j++) { if (dis[j] > dis[u] + map[u][j]) { dis[j] = dis[u] + map[u][j]; if (!vis[j]) { vis[j] = 1; Q.push(j); } } } } } int main() { coor a, b; int S, T, A, B, TT[410]; while (~scanf("%d%d%d%d", &S, &T, &A, &B)) { double minn = inf; for (int i = 0; i < 4 * S; i++) for (int j = 0; j < 4 * S; j++) map[i][j] = inf; for (int i = 0; i < 4 * S; i += 4) { for (int j = 0; j < 3; j++) scanf("%d%d", &e[i + j].x, &e[i + j].y); scanf("%d", &TT[i]); Seeking(e + i); } for (int i = 0; i < 4 * S; i += 4) { for (int j = 0; j < 4; j++) { a = e[i + j]; for (int k = i + j + 1; k < i + 4; k++) { b = e[k]; map[k][i + j] = map[i + j][k] = TT[i] * sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } for (int k = i + 4; k < 4 * S; k++) { b = e[k]; map[k][i + j] = map[i + j][k] = T * sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } } } for (int i = 0; i < 4; i++) { int u = (A - 1) * 4 + i; Bellman_Ford(u, S); for (int j = 0; j < 4; j++) { int v = (B - 1) * 4 + j; if (minn > dis[v]) minn = dis[v]; } } printf("%.2lf\n", minn); } return 0; }