题目
https://www.rqnoj.cn/problem/86
题目描述
背景
为了统计小球的方案数,平平已经累坏了。于是,他摘掉了他那800度的眼镜,躺在树下休息。
后来,平平发现树上有一个特别不一样的水果,又累又饿的平平打算去把它摘下来。
题目描述
现在,将大树以一个N个节点的无向图的形式给出,每个节点用坐标(Xi,Yi)来表示表示,平平要从第一个点爬到第N个点,除了从一个节点爬向另一个相邻的节点以外,他还有一种移动方法,就是从一个节点跳下,到达正下方的某个节点(之间可隔着若干个点和边),即当
X
j
=
X
i
a
n
d
Y
i
<
Y
j
Xj=Xi\ and\ Yi<Yj
Xj=Xi and Yi<Yj 时,平平就可以从j节点下落到i节点,他下落所用时间满足自由落体公式,
t
=
(
Y
j
−
Y
i
)
∗
2
g
t=\sqrt{\frac{(Yj-Yi)*2}{g}}
t=g(Yj−Yi)∗2 (注意:
g
g
g取
10
10
10)。如果出现两线相交的情况,我们不认为它们是相通的。
数据规模
对于100%数据,
1
<
=
N
<
=
100
,
1
<
=
V
<
=
10
,
0
<
=
X
,
Y
<
=
100
1<=N<=100,1<=V<=10,0<=X,Y<=100
1<=N<=100,1<=V<=10,0<=X,Y<=100.
建议使用
e
x
t
e
n
d
e
d
(
p
a
s
)
extended(pas)
extended(pas)或
d
o
u
b
l
e
double
double(
c
a
n
d
c
+
+
c and c++
candc++)计算,我们对于精度造成的误差将不予重测。
输入格式
两个整数
N
N
N,
V
V
V,
N
N
N表示节点个数,V表示平平爬树的速度。
接下来
N
N
N行,每行包含
3
3
3个整数
X
X
X,
Y
Y
Y,
F
F
F,
X
X
X,
Y
Y
Y是这个点的坐标,
F
F
F是他的父节点(F一定小于这个点的标号,第一行的
F
F
F为
0
0
0)。
注意:两节点间距离按欧几里德距离计算
d
i
s
=
(
x
1
–
x
2
)
2
+
(
y
1
–
y
2
)
2
dis=\sqrt{(x1 – x2 )^{2}+ ( y1 – y2 )^{2}}
dis=(x1–x2)2+(y1–y2)2
输出格式
输出仅包括一行,从
1
1
1到
N
N
N所用的最少所需时间
T
T
T,保留两位小数。
解题思路Floyd
普及组难度
<
<
−
−
<<--
<<−−根据题意,处理好初始化条件,直接用
F
L
O
Y
D
FLOYD
FLOYD做一遍最短路。
代码
#include<cstdio>
#include<cmath>
#define rr register
using namespace std;
int n,x[105],y[105],z; double v,f[105][105];
inline int pinf(int x){return x*x;}
inline double minn(double x,double y){if (x<y) return x; return y;}
int main()
{
scanf("%d%lf",&n,&v);
for (rr int i=1;i<=n;i++)
for (rr int j=1;j<=n;j++)
f[i][j]=1e8;
for (rr int i=1;i<=n;i++){
scanf("%d%d%d",&x[i],&y[i],&z);
f[z][i]=f[i][z]=sqrt((double)(pinf(x[z]-x[i])+pinf(y[z]-y[i])));
f[z][i]/=v; f[i][z]/=v;
}
for (rr int j=1;j<=n;j++)
for (rr int i=1;i<=n;i++)
if (x[i]==x[j]&&y[i]<y[j])
f[j][i]=minn(sqrt(((double)(y[j]-y[i]))/5.0),f[j][i]);
for (rr int k=1;k<=n;k++)
for (rr int i=1;i<=n;i++)
for (rr int j=1;j<=n;j++)
if (k!=i&&i!=j&&k!=j)
f[i][j]=minn(f[i][j],f[i][k]+f[k][j]);
printf("%.2lf",f[1][n]);
}