落谷 P1027 Car的旅行路線

題目大意

給出每一個城市的飛機場的座標,然後讓你找出當前城市到給出城市的最短距離

solution

算法

顯然我們是用最短路做,因爲s只有100,四個飛機場的話只有400
所以我就用floyd了.

求第四個飛機場的座標

先用向量法找出直角邊,再利用對角線上的點橫座標之和等於中點橫座標的二倍求出。

a[1] = read(), b[1] = read(), a[2] = read(), b[2] = read();
	a[3] = read(), b[3] = read(), Ti = read();
if ((a[1] - a[2]) * (a[2] - a[3]) + (b[1] - b[2]) * (b[2] - b[3]) == 0)
    a[4] = a[1] + a[3] - a[2], b[4] = b[1] + b[3] - b[2];
if ((a[1] - a[3]) * (a[2] - a[3]) + (b[1] - b[3]) * (b[2] - b[3]) == 0)
	a[4] = a[1] + a[2] - a[3], b[4] = b[1] + b[2] - b[3];
if ((a[1] - a[3]) * (a[2] - a[1]) + (b[1] - b[3]) * (b[2] - b[1]) == 0)
	a[4] = a[3] + a[2] - a[1], b[4] = b[3] + b[2] - b[1];

next

找完第四個點的座標之後,我們要先把這四個點連起來,順便存一下編號和座標
後邊兩兩座標連邊的時候能用到

最後floyd, 求A城市中的每一個飛機場,到B城市中每一個飛機場的距離取一個最小值.

code

/*
	Auther:_Destiny
	time:2020.4.29
*/
#include <bits/stdc++.h>
#define ll long long
#define N 100010
#define M 410

using namespace std;
int T, A, B; double s, t, Ti;
double dis[M][M];
double a[5], b[5];
map<int, pair<double, double> >ma;
int E[5];
int S[5];

int read() {
	int s = 0, f = 0; char ch = getchar();
	while (!isdigit(ch)) f |= (ch == '-'), ch = getchar();
	while (isdigit(ch)) s = s * 10 + (ch ^ 48), ch = getchar();
	return f ? -s : s;
}

double maha(double a1, double b1, double a2, double b2) {
	return sqrt((a1 - a2) * (a1 - a2) + (b1 - b2) * (b1 - b2));
}

int main() {
	T = read();
	while (T--) {
		s = read(), t = read(), A = read(), B = read();
		for (int i = 1; i <= s * 4; i++)
			for (int j = 1; j <= s * 4; j++)
				dis[i][j] = 1e9;
		int cnt = 0;
		for (int k = 1; k <= s; k++) {
			a[1] = read(), b[1] = read(), a[2] = read(), b[2] = read();
			a[3] = read(), b[3] = read(), Ti = read();
			if ((a[1] - a[2]) * (a[2] - a[3]) + (b[1] - b[2]) * (b[2] - b[3]) == 0)
        		a[4] = a[1] + a[3] - a[2], b[4] = b[1] + b[3] - b[2];
        	else if ((a[1] - a[3]) * (a[2] - a[3]) + (b[1] - b[3]) * (b[2] - b[3]) == 0)
	        	a[4] = a[1] + a[2] - a[3], b[4] = b[1] + b[2] - b[3];
	    	else if ((a[1] - a[3]) * (a[2] - a[1]) + (b[1] - b[3]) * (b[2] - b[1]) == 0)
	    		a[4] = a[3] + a[2] - a[1], b[4] = b[3] + b[2] - b[1];
	    	ma[cnt + 1] = make_pair(a[1], b[1]);
	    	ma[cnt + 2] = make_pair(a[2], b[2]);
	    	ma[cnt + 3] = make_pair(a[3], b[3]);
	    	ma[cnt + 4] = make_pair(a[4], b[4]);
			for (int i = 1; i <= 4; i++)
				for (int j = 1; j <= 4; j++)
					if (i != j) {
						dis[cnt + i][cnt + j] = maha(a[i], b[i], a[j], b[j]) * Ti;
						dis[cnt + j][cnt + i] = dis[cnt + i][cnt + j];
					}
			if (k == A) {
				for (int i = 1; i <= 4; i++)
					S[i] = cnt + i;
			} else if (k == B) {
				for (int i = 1; i <= 4; i++)
					E[i] = cnt + i;
			}
			cnt += 4;
		}
//		if (cnt == 4 * s) puts("11111");
		for (int i = 1; i <= cnt; i++)
			for (int j = 1; j <= cnt; j++) 
				if ((i - 1) / 4 != (j - 1) / 4) {
					dis[i][j] = maha(ma[i].first, ma[i].second, ma[j].first, ma[j].second) * t;
					dis[j][i] = dis[i][j];
				}
		for (int k = 1; k <= cnt; k++)
			for (int i = 1; i <= cnt; i++)
				for (int j = 1; j <= cnt; j++)
					dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
		double ans = 1e9;
		for (int i = 1; i <= 4; i++)
			for (int j = 1; j <= 4; j++)
				ans = min(ans, dis[S[i]][E[j]]);
		printf("%.1lf\n", ans);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章