洛谷 P1027 Car的旅行路线

      洛谷 P1027 Car的旅行路线

题目描述

又到暑假了,住在城市 A 的 Car 想和朋友一起去城市 B 旅游。她知道每个城市都有 4 个飞机场,分别位于一个矩形的 4 个顶点上,同一个城市中 2 个机场之间有 1 条笔直的高速铁路,第 I 个城市中高速铁路了的单位里程价格为 Ti ,任意两个不同城市的机场之间均有航线,所有航线单位里程的价格均为 

图例(从上而下)

机场
高速铁路
飞机航线

  注意:图中并没有标出所有的铁路与航线。

那么 Car 应如何安排到城市B的路线才能尽可能的节省花费呢?她发现这并不是一个简单的问题,于是她来向你请教。

找出一条从城市 A 到 B 的旅游路线,出发和到达城市中的机场可以任意选取,要求总的花费最少。

输入输出格式

输入格式:

第一行为一个正整数 n (≤ ≤ 10 ),表示有 n 组测试数据。

每组的第一行有 4 个正整数 s,t,A,B 。

S ( ≤ 100 )表示城市的个数, t 表示飞机单位里程的价格, A , B 分别为城市 A , B 的序号,( ≤ A,≤ S )。

接下来有 S 行,其中第 I 行均有 7 个正整数 xi1,yi1,xi2,yi2,xi3,yi3,Ti ,这当中的( xi1,yi1 ),( xi2,yi2),( xi3,yi3 )分别是第 i 个城市中任意 3 个机场的坐标, Ti 为第 i 个城市高速铁路单位里程的价格。

输出格式:

共有 n 行,每行 1 个数据对应测试数据。 保留一位小数。

输入输出样例

输入样例#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
输出样例#1: 复制
47.5

思路:根据题目将图中的边分别求出后建图,跑spfa求最短路

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<cmath>
#define M 160005
using namespace std;
queue<int>que;
int vis[410];
double ans = 0x7f7f7f7f;
int n, s, t, a, b, tot, sum;
double cap[M], dis[405];
int to[M], net[M], head[405];
struct nond {
    int x[5], y[5], num[5];
    double t;
} v[110];
struct none {
    int l, r;
};
void add(int u,int v,double w) {
    to[++tot] = v; cap[tot] = w; net[tot] = head[u]; head[u] = tot;
    to[++tot] = u; cap[tot] = w; net[tot] = head[v]; head[v] = tot;
}
none find(int p) {
    none tmp;
    double maxn = -99999;
    for(int i = 1; i <= 3; i++)
        for(int j = i+1; j <= 3; j++) {
            double x = (v[p].x[i]-v[p].x[j])*(v[p].x[i]-v[p].x[j])+(v[p].y[i]-v[p].y[j])*(v[p].y[i]-v[p].y[j]);
            if(x > maxn) {
                maxn = x;
                tmp.l = i;
                tmp.r = j;
            }
        }
    return tmp;
}
int findx(int p) {
    none tmp = find(p);
    int k;
    if(tmp.l==1 && tmp.r==2 || tmp.l==2 && tmp.r==1) k = 3;
    else if(tmp.l==1 && tmp.r==3 || tmp.l==3 && tmp.r==1) k = 2;
    else if(tmp.l==2 && tmp.r==3 || tmp.l==3 && tmp.r==2) k = 1;
    return v[p].x[tmp.l] + v[p].x[tmp.r] - v[p].x[k];
}
int findy(int p) {
    none tmp = find(p);
    int k;
    if(tmp.l==1 && tmp.r==2 || tmp.l==2 && tmp.r==1) k = 3;
    else if(tmp.l==1 && tmp.r==3 || tmp.l==3 && tmp.r==1) k = 2;
    else if(tmp.l==2 && tmp.r==3 || tmp.l==3 && tmp.r==2) k = 1;
    return v[p].y[tmp.l] + v[p].y[tmp.r] - v[p].y[k];
}
void build() {
    for(int i = 1; i <= s; i++) {
        for(int a = 1; a <= 4; a++)
            for(int b = a+1; b <= 4; b++) {
                double x = sqrt((v[i].x[a]-v[i].x[b])*(v[i].x[a]-v[i].x[b])+(v[i].y[a]-v[i].y[b])*(v[i].y[a]-v[i].y[b]))*v[i].t;
                add(v[i].num[a], v[i].num[b], x);
            }
        for(int j = i+1; j <= s; j++)
            for(int a = 1; a <= 4; a++)
                for(int b = 1; b <= 4; b++) {
                    double x = t*sqrt((v[i].x[a]-v[j].x[b])*(v[i].x[a]-v[j].x[b])+(v[i].y[a]-v[j].y[b])*(v[i].y[a]-v[j].y[b]));
                    add(v[i].num[a], v[j].num[b], x);
                }
    }
}
void spfa(int s) {
    memset(vis, 0, sizeof vis);
    memset(dis, 0x7f, sizeof dis);
    while(!que.empty()) que.pop();
    que.push(s); dis[s] = 0; vis[s] = 1;
    while(!que.empty()) {
        int now = que.front(); que.pop(); vis[now] = 0;
        for(int i = head[now]; i; i = net[i])
            if(dis[to[i]] > dis[now]+cap[i]) {
                dis[to[i]] = dis[now]+cap[i];
                if(!vis[to[i]]) vis[to[i]] = 1, que.push(to[i]);
            }
    }
}
int main() {
    scanf("%d", &n);
    while(n--) {
        scanf("%d%d%d%d", &s, &t, &a, &b);
        for(int i = 1; i <= s; i++) {
            int x1, y1, x2, y2, x3, y3, x4, y4, t;
            cin >> v[i].x[1] >> v[i].y[1] >> v[i].x[2] >> v[i].y[2] >> v[i].x[3] >> v[i].y[3] >> v[i].t;
            v[i].x[4] = findx(i);
            v[i].y[4] = findy(i);
            for(int j = 1; j <= 4; j++) v[i].num[j] = ++sum;
        }
        build();
        for(int i = 1; i <= 4; i++) {
            spfa(v[a].num[i]);
            ans = min(ans, min(dis[v[b].num[1]], min(dis[v[b].num[2]], min(dis[v[b].num[3]], dis[v[b].num[4]]))));
        }
        printf("%.1lf", ans);
        ans = 0x7f7f7f;
    }
    return 0;
}
View Code

 




posted @ 2018-07-20 17:21  落云小师妹  阅读(203)  评论(0编辑  收藏  举报