The 19th ZCPC -G. Easy Glide

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值