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