Car的旅行路线
题目描述
又到暑假了,住在城市A的Car想和朋友一起去城市B旅游。她知道每个城市都有四个飞机场,分别位于一个矩形的四个顶点上,同一个城市中两个机场之间有一条笔直的高速铁路,第I个城市中高速铁路了的单位里程价格为Ti,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为t。
图例(从上而下)
机场
高速铁路
飞机航线
注意:图中并没有标出所有的铁路与航线。
那么Car应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。
任务:找出一条从城市A到B的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。
输入描述
第一行为一个正整数n( 0 ≤ n ≤ 10 ),表示有n组测试数据。
每组的第一行有4个正整数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个城市中任意3个机场的坐标,Ti 为第i个城市高速铁路单位里程的价格。
输出描述
共有n行,每行1个数据对应测试数据(最小花费)。保留一位小数。
示例
输入
1
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.5
#include<bits/stdc++.h>
using namespace std;
const int N = 1e2 + 7;
const int M = 1e6 + 7;
struct City {
double x[4], y[4]; double T;
}city[M];
int head[M], ver[M], nex[M]; double len[M]; int tot, v[M];
double d[M];
inline double distance(double x, double y, double xx, double yy) {
return sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
}
void add(int x, int y, double z) {
ver[++tot] = y; nex[tot] = head[x]; head[x] = tot; len[tot] = z;
}
int q[M];
void spfa(int a, int b, int n) {
double ret = 1e18;
for (int cas = 1; cas <= 4; cas++) {
for (int i = 1; i <= n; i++) d[i] = 1e18;
memset(v, 0, sizeof(v));
int x = 4 * a - 4 + cas;
int l = 0, r = 0;
d[x] = 0;
q[r++] = x;
while (l < r) {
int x = q[l++];
v[x] = 0;
for (int i = head[x]; i; i = nex[i]) {
if (d[ver[i]] > d[x] + len[i]) {
d[ver[i]] = d[x] + len[i];
if (!v[ver[i]]) q[r++] = ver[i], v[ver[i]] = 1;
}
}
}
for (int i = 1; i <= 4; i++) {
int x = b * 4 - 4 + i;
ret = min(ret, d[x]);
}
}
printf("%.1lf\n", ret);
}
bool check(int p, int a, int b, int c) {
double dx = city[p].x[a] - city[p].x[b];
double dy = city[p].y[a] - city[p].y[b];
double px = city[p].x[b] - city[p].x[c];
double py = city[p].y[b] - city[p].y[c];
return dx * dy + px * py == 0;
}
void solve() {
int s, a, b; double t;
memset(head, 0, sizeof(head));
tot = 0;
cin >> s >> t >> a >> b;
if (a == b) {
printf("0.0\n");
return;
}
for (int i = 1; i <= s; i++) {
for (int j = 0; j < 3; j++) cin >> city[i].x[j] >> city[i].y[j];
int ps = 0;
if (check(i, 0, 1, 2)) ps = 1;
if (check(i, 0, 2, 1)) ps = 2;
if (check(i, 1, 0, 2)) ps = 0;
if (ps == 0) {
city[i].x[3] = city[i].x[1] + city[i].x[2] - city[i].x[0];
city[i].y[3] = city[i].y[1] + city[i].y[2] - city[i].y[0];
}
else if (ps == 1) {
city[i].x[3] = city[i].x[0] + city[i].x[2] - city[i].x[1];
city[i].y[3] = city[i].y[0] + city[i].y[2] - city[i].y[1];
}
else {
city[i].x[3] = city[i].x[1] + city[i].x[0] - city[i].x[2];
city[i].y[3] = city[i].y[1] + city[i].y[0] - city[i].y[2];
}
cin >> city[i].T;
}
for (int i = 1; i <= s; i++) {
for (int j = 0; j < 4; j++) {
for (int k = j + 1; k < 4; k++) {
double dis = distance(city[i].x[j], city[i].y[j], city[i].x[k], city[i].y[k]);
int x = 4 * i - 4 + j + 1, y = 4 * i - 4 + 1 + k;
add(x, y, dis * city[i].T);
add(y, x, dis * city[i].T);
}
}
}
for (int i = 1; i <= s; i++) {
for (int j = i + 1; j <= s; j++) {
for (int k = 0; k < 4; k++) {
for (int l = 0; l < 4; l++) {
int x = i * 4 + k + 1 - 4, y = j * 4 + l + 1 - 4;
double dis = distance(city[i].x[k], city[i].y[k], city[j].x[l], city[j].y[l]);
add(x, y, dis * t);
add(y, x, dis * t);
}
}
}
}
spfa(a, b, 4 * s);
}
int main() {
int n;
cin >> n;
while (n--) solve();
return 0;
}

浙公网安备 33010602011771号