Grammy is playing a boring racing game named Easy Gliding. The game's main content is to reach the destination as fast as possible by walking or gliding. The fastest player wins.
Each player controls a character on a two-dimensional plane. A character can walk at any moment with a speed of V1. Especially, when a character touches a gliding point, he/she can glide with a speed of V2for the following 3 seconds. It is guaranteed that V1<V2.
Now Grammy locates at point S and she knows the coordinates of all the gliding points p1,p2,…,pn. The goal is to reach point T as fast as possible. Could you tell her the minimum time she has to spend to reach point T?
Input
The first line contains one integer nn (1≤n≤1000), denoting the number of gliding points.
The following nn lines describe the gliding points. The ii-th line contains two integers xi,yixi,yi (1000000≤xi,yi≤1000000), representing the coordinates of the ii-th gliding point pi.
The next line contains four integers Sx,Sy,Tx,Ty (−1000000≤Sx,Sy,Tx,Ty≤1000000), representing the coordinates of S and T.
The next line contains two integers V1,V2 (1≤V1<V2≤1000000), representing the speed of walking and gliding.
Output
Output the minimum time Grammy has to spend to reach point TT in one line. Your answer will be considered correct if its absolute or relative error does not exceed 10−6.
Examples
input
2
2 1
0 3
0 0 4 0
10 11
output
0.400000000000
input
2
2 1
-2 0
0 0 4 0
1 2
output
3.354101966250
input
2
2 1
-2 0
0 0 4 0
1 10000
output
2.000600000000
解析 :分为三部分:起点,加速点,终点。然后我们求出建图求出
1.起点到每个加速点的时间 2.加速点相互之间的到达所需时间 3.加速点到终点的时间 4.起点直接到终点。
虽然坐标是两个参数,但是我们可以算出两点之间的所需时间,然后用 i 来代表某个点,起点为0,终点为n+1,加速点为1~n,两点的时间其实就是权重,然后利用通常最短路算法计算即可。
#include <stdio.h>
#include <vector>
#include <queue>
#include <math.h>
using namespace std;
const int N=1100;
int n,qx,qy,zx,zy,v1,v2;
double dist[N];
bool st[N];
vector<pair<int,int>> v;//存加速点的坐标
vector<pair<int,double>> gra[N];//存邻边
double jl(int x1,int y1,int x2,int y2)//计算两点距离
{
return sqrt((x1*1.0-x2)*(x1-x2)+(y1*1.0-y2)*(y1-y2));
}
void solve()//最短路算法,此处是spfa
{
for(int i=0;i<=n+1;i++) dist[i]=1e18;
dist[0]=0;
st[0]=true;
queue<int> q;
q.push(0);
while(q.size())
{
int x=q.front();
q.pop();
st[x]=false;
for(int i=0;i<gra[x].size();i++)
{
int node=gra[x][i].first;
double len=gra[x][i].second;
if(dist[node]>dist[x]+len)
{
dist[node]=dist[x]+len;
if(!st[node]) q.push(node);
}
}
}
printf("%.12lf\n",dist[n+1]);
}
int main()
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int a,b;
scanf("%d%d",&a,&b);
v.push_back({a,b});//存一下加速点的距离
}
scanf("%d%d%d%d%d%d",&qx,&qy,&zx,&zy,&v1,&v2);
//此处是算加速点内部的相互到达时间
for(int i=0;i<n;i++)
{
for(int j=i+1;j<n;j++)
{
int x1=v[i].first,y1=v[i].second;
int x2=v[j].first,y2=v[j].second;
double k=jl(x1,y1,x2,y2),t;//计算两点距离
if(k>3*v2) t=(k-3*v2)/v1+3;//如果加速时间内无法到达
else t=k/v2;
gra[i+1].push_back({j+1,t});
gra[j+1].push_back({i+1,t});
}
}
//起点到加速点的所需时间
for(int i=0;i<n;i++)
{
int x1=v[i].first,y1=v[i].second;
double k=jl(x1,y1,qx,qy),t;
t=k/v1;//因为起点到加速点过程中肯定没有V2
gra[0].push_back({i+1,t});
}
//起点到终点
gra[0].push_back({n+1,jl(qx,qy,zx,zy)/v1*1.0});
//加速点到终点的时间
for(int i=0;i<n;i++)
{
int x1=v[i].first,y1=v[i].second;
double k=jl(x1,y1,zx,zy),t;
if(k>3*v2) t=(k-3*v2)/v1+3;
else t=k/v2;
gra[i+1].push_back({n+1,t});
}
solve();
return 0;
}