您的位置:首页 > 其它

【图论】【RQNOJ】智捅马蜂窝

2010-07-03 16:46 239 查看

题目描述

背景
为了统计小球的方案数,平平已经累坏了。于是,他摘掉了他那800度的眼镜,躺在树下休息。
后来,平平发现树上有一个特别不一样的水果,又累又饿的平平打算去把它摘下来。
题目描述
现在,将大树以一个N个节点的无向图的形式给出,每个节点用坐标(Xi,Yi)来表示表示,平平要从第一个点爬到第N个点,除了从一个节点爬向另一个相邻的节点以外,他还有一种移动方法,就是从一个节点跳下,到达正下方的某个节点(之间可隔着若干个点和边),即当Xj=Xi and Yi<Yj 时,平平就可以从j节点下落到i节点,他下落所用时间满足自由落体公式,t=sqrt((Yj-Yi)*2/g) (注意:g取10)。如果出现两线相交的情况,我们不认为它们是相通的。
数据规模
对于100%数据,1<=N<=100,1<=V<=10,0<=X,Y<=100.
建议使用extended(pas)或double(c and c++)计算,我们对于精度造成的误差将不予重测。

输入格式

两个整数N,V,N表示节点个数,V表示平平爬树的速度。
接下来N行,每行包含3个整数X,Y,F,X,Y是这个点的坐标,F是他的父节点(F一定小于这个点的标号,第一行的F为0)。
注意:两节点间距离按欧几里德距离计算 dis = sqrt( ( x1 – x2 ) 2+ ( y1 – y2 )2 )

输出格式

输出仅包括一行,从1到N所用的最少所需时间T,保留两位小数。

样例输入

#include<stdio.h>
#include<math.h>
const int g=10;
double ans_t,t[101][101],min_t[101];
bool vi[101];
struct ss
{
int x,y;
} a[101];
int n,v;
void init()
{
int temp;
scanf("%d%d",&n,&v);
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
t[i][j]=9999999;
for (int i=1;i<=n;++i)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&temp);
t[i][temp]=sqrt((a[i].x-a[temp].x)*(a[i].x-a[temp].x)+(a[i].y-a[temp].y)*(a[i].y-a[temp].y))/v;
t[temp][i]=t[i][temp];
}
}
int main()
{
init();
for (int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
if (i!=j)
if (a[i].x==a[j].x)
if (a[i].y<a[j].y)
if ((sqrt((a[j].y-a[i].y)*2/g))<t[j][i])
t[j][i]=(sqrt((double)((a[j].y-a[i].y)*2)/g));
for (int i=1;i<=n;++i) min_t[i]=t[1][i];
vi[1]=true;
while (1)
{
int k=0; double min=99999;
for (int i=1;i<=n;++i)
if (!vi[i])
if (min_t[i]<min)
{
k=i;
min=min_t[i];
}
if (k==0) break;
vi[k]=true;
for (int i=1;i<=n;++i)
if (!vi[i])
if (min_t[k]+t[k][i]<min_t[i])
min_t[i]=min_t[k]+t[k][i];
}
printf("%.2f/n",min_t
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: