Klee‘s Wonderful Adventure---最短路

任意门

Today little Klee wanted to go on an adventure outside. Klee wanted to go to so many places to play, but finally, she could only go to one place to play and she can pass away any number of times in other places.

First of all, let’s consider the plane where Klee is located as a two-dimensional plane, which is divided into four quadrants, and there are n points in the whole plane. Klee can only move directly from one point to another for each movement.

Since each quadrant represents a different country, the maximum speed that can be achieved differs for each quadrant. The ranges and maximum speeds of these four quadrants are defined as follows:
在这里插入图片描述
If two points are in the same quadrant, Klee can reach the maximum speed given in that quadrant. For example, in one movement, if Klee’s start point and Klee’s endpoint are both located in the first quadrant, the maximum speed is v1.

If the two points are not in the same quadrant, then Klee’s speed must not be greater than v0 to transfer directly in both quadrants. For example, in one movement, if Klee’s start point is located in the first quadrant and Klee’s endpoint is located in the second quadrant, the maximum speed is v0 in this movement.

Now, given the initial index of the point that Klee is in and the final index of the point that Klee finally wants to play, please find the minimum time needed for Klee to get from the initial point to the final point.

Input
The First line is an integer n (1≤n≤3⋅103) indicating the number of points.

The second line contains 5 integers v1,v2,v3,v4,v0 (1≤v1,v2,v3,v4,v0≤105) as described above.

The third line contains two integers s,t (1≤s,t≤n), indicating the initial index of the point and the final index of the point.

For the following n lines, the i-th line contains two integers xi,yi (−105≤xi,yi≤105,xi≠0,yi≠0), indicating the coordinate of the i-th point.

We ensure that there is no overlap between the two points(which means for any point i and j, we can ensure that xi=xj and yi=yj do not occur simultaneously).

Output
Output one line containing one integer indicating the minimum time needed for Klee to get from the initial point to the final point.

Your answer will be accepted if the absolute or relative error does not exceed 10−6. Formally, let your answer be a, and the jury’s answer is b. Your answer is considered correct if |a−b|max(1,|b|)≤10−6.

Examples
input

3
1 2 3 4 5
1 3
1 -5
1 -1
1 1

output

1.2000000000

input

4
5 1 1 10 1
1 4
1 1
2 1
2 -1
1 -2

output

2.3414213562

input

3
1 1 1 1 100
1 3
1 1
2 -1
1 -100

output


1.0100000000

Note
In the second test case:
在这里插入图片描述

Klee needs to move from point 1 to point 4.

She will first move from point 1 to point 3 with a speed of v0, and then from point 3 to point 4 at a speed of v4.

给定了距离和时间,那么我们可以求出每个点之间的时间,那么我们可以很显然的想到最短路问题。
直接使用dijkstra跑就行了。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
 
const int maxn = 100100;
int n;
double v1, v2, v3, v4, v0;
int s, t;
int vis[3010];
double last;
double dis[3010][3010];
double to[3010];
 
struct  node{
    double x;
    double y;
}z[maxn];
 
double get_dis(const node & a, const node & b){
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
 
void dij(int s){
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; i++) to[i] = 0x3f3f3f;
    to[s] = 0;
    for(int i = 1; i <= n; i++){
        int t = 0;
        for(int j = 1; j <= n; j++){
            if(!vis[j] && (t == 0 || to[t] > to[j])){
                t = j;
            }
        }
        vis[t] = 1;
        for(int i = 1; i <= n; i++){
            to[i] = min(to[i], to[t] + dis[t][i]);
        }
    }
}
 
int main(){
    cin >> n;
    cin >> v1 >> v2 >> v3 >> v4 >> v0;//读入象限和默认速度
    cin >> s >> t;//起始位置和截止位置的点编号
    for(int i = 1; i <= n; i++) cin >> z[i].x >> z[i].y;
    for(int i = 1; i <= n; i++){//建立以从i运动到j的时间为val的最短路
        for(int j = 1; j <= n; j++){
            if(i == j){
                dis[i][j] = 0;
                continue;
            }
            if(z[i].x >= 1 && z[i].y >= 1){
                if(z[j].x >= 1 && z[j].y >= 1) dis[i][j] = get_dis(z[i], z[j]) / v1;
                else dis[i][j] = get_dis(z[i], z[j]) / v0;
            }
            if(z[i].x <= -1 && z[i].y >= 1){
                if(z[j].x <= -1 && z[j].y >= 1) dis[i][j] = get_dis(z[i], z[j]) / v2;
                else dis[i][j] = get_dis(z[i], z[j]) / v0;
            }
            if(z[i].x <= -1 && z[i].y <= -1){
                if(z[j].x <= -1 && z[j].y <= -1) dis[i][j] = get_dis(z[i], z[j]) / v3;
                else dis[i][j] = get_dis(z[i], z[j]) / v0;
            }
            if(z[i].x >= 1 && z[i].y <= -1){
                if(z[j].x >= 1 && z[j].y <= -1) dis[i][j] = get_dis(z[i], z[j]) / v4;
                else dis[i][j] = get_dis(z[i], z[j]) / v0;
            }
            last = max(last, dis[i][j]);
        }
    }
    dij(s);
    printf("%.10lf\n",to[t]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值