• 洛谷 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



  • 相关阅读:
    java数组的相关方法
    spring boot 文件目录
    mysql 数据库安装,datagrip安装,datagrip连接数据库
    linux maven 的安装与配置
    java String字符串常量常用方法
    java 命名规范
    deepin 安装open jdk
    jetbrains(idea,webstorm,pycharm,datagrip)修改背景,主题,添加特效,汉化
    JVM学习(九)volatile应用
    JVM学习(八)指令重排序
  • 原文地址:https://www.cnblogs.com/v-vip/p/9342632.html
Copyright © 2020-2023  润新知