第一次手搓dijkstra,以为是精度问题结果居然是模板写错(ps.我发四以后再不也写错)
首先这题是有不超过202个点(算上家和学校),距离化成时间来计算会比较方便哦。然后就是要用double型还来处理,数据比较恶心,输入没有规定怎么停,就是要用EOF。
有地铁的点之间要算时间,然后再是初始化步行的点之间的时间。万事俱备,需要套dijkstra算法即可。(ps.一定要自己手搓,以后才不会写错)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
double map[205][205];//记录两点之间的需要用的时间
double d[205];//到源点的最短的距离(时间)
int v[205];//这个点取过没
struct point
{
double x,y;
} p[205];
int main()
{
double xx,yy;
scanf("%lf%lf%lf%lf",&p[0].x,&p[0].y,&p[1].x,&p[1].y);
int n=2;
int flag=0;
memset(map,0,sizeof(map));
while(~scanf("%lf%lf",&xx,&yy))
{
if(xx==-1&&yy==-1)
{
flag=0;
continue;//-1 -1的时候不记录进去
}
p[n].x=xx;
p[n].y=yy;
if(flag)//有两个站才能开地铁啊。
{
double r=p[n].x-p[n-1].x;
double s=p[n].y-p[n-1].y;
map[n][n-1]=map[n-1][n]=sqrt(r*r+s*s)/40000;//换算成时间比较好计算
}
n++;
flag=1;
}
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
if(i!=j&&map[i][j]==0.0)
{
double r=p[i].x-p[j].x;
double s=p[i].y-p[j].y;
map[i][j]=map[j][i]=sqrt(r*r+s*s)/10000;//所有还没有算过的边
}
}
}
memset(v,0,sizeof(v));
for(int i=0; i<n; i++) d[i]=map[0][i];//每个点到源点0的距离//dijkstra算法
for(int i=0; i<n; i++)
{
double mini=99999999999;
int u;
for(int j=0; j<n; j++)
if(!v[j]&&d[j]<mini)
{
u=j;
mini=d[j];//寻找此时到源点距离最近的点
}
v[u]=1;
for(int j=0; j<n; j++)
{
d[j]=min(d[j],d[u]+map[u][j]);//更新每个点到源点0的距离
}
}
double ans=60*d[1];
printf("%0.0lf\n",ans);
return 0;
}