落谷 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);
	}
}

猜你喜欢

转载自www.cnblogs.com/zzz-hhh/p/12802864.html
今日推荐