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;
}
posted @ 2020-08-17 20:57  HighLights  阅读(108)  评论(0)    收藏  举报