/*
zoj_1891 最短路
泪奔~~o(>_<)o ~~ 终于过了。。。细说一下坑爹的做题过程
process:
1.乍看觉得题目好像木有说清楚每个点只出现一次,dijk的话如果一个点出现多次感觉不好处理。
于是想到了floyd
2.然后floyd写了,结果MLE了。。
3.看了下别人的代码,发现基本都dijk过的。看来每个点必定只出现一次了。
4.最坑爹的是这个时候,dijk轻松写完了,却死都过不了。。感觉自己的思路跟大家都差不多。
判断两点是不是在一条线路上,如果在一条线路上那么两点可以坐地铁到达为最短,否则走路。
其实上面这句话是错的,可是我就是死都转不过弯,坑爹啊。正确的是在同一线路上的相邻两
点才必为坐地铁最短。具体见代码。
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <limits.h>
#include <string.h>
#include <cmath>
#define N 210
using namespace std;
double point[N][2];
int id[N];
double dist[N];
double count( int i,int j )
{
double t1,t2;
t1=(point[i][0]-point[j][0])*(point[i][0]-point[j][0]);
t2=(point[i][1]-point[j][1])*(point[i][1]-point[j][1]);
if( id[i]!=id[j] || ( i!=j-1 && j!=i-1 ) )// 这里没加( i!=j-1 && j!=i-1 ),必须相邻!!一个晚上时间啊!!
return sqrt( t1+t2 )/10000.0*60.0;
return sqrt( t1+t2 )/40000.0*60.0;
}
void dijkstra( int sta,int n )
{
int i,j,mark,mini;
bool flag[210];
memset( flag,0,sizeof(flag) );
memset( dist,0,sizeof(dist) );
flag[sta]=1;
for( i=1;i<=n;i++ )
{
mini=INT_MAX;
for( j=1;j<=n;j++ )
{
if( flag[j]==0 )
{
if( dist[j]>dist[sta]+count( sta,j ) )
dist[j]=dist[sta]+count( sta,j );
else if( dist[j]==0 )
dist[j]=dist[sta]+count( sta,j );
if( mini>dist[j] && dist[j]!=0 )
{
mini=dist[j];
mark=j;
}
}
}
if( mini==INT_MAX ) break;
sta=mark;
flag[sta]=1;
}
}
int main()
{
//freopen( "AAA_a.txt","r",stdin );
int i,j,n;
while( scanf( "%lf%lf",&point[1][0],&point[1][1] )!=EOF )
{
scanf( "%lf%lf",&point[2][0],&point[2][1] );
id[1]=1 , id[2]=2 ;
i=3 , j=3 ;
while( scanf("%lf%lf",&point[i][0],&point[i][1])&&!(point[i][0]==-1&&point[i][1]==-1) )
{
id[i++]=j;
while( scanf("%lf%lf",&point[i][0],&point[i][1])&&!(point[i][0]==-1&&point[i][1]==-1) )
id[i++]=j;
j++;
}
n=i-1;
dijkstra( 1,n );
printf( "%.0lf\n",dist[2] );
}
return 0;
}
zoj 1891
最新推荐文章于 2021-02-27 01:57:38 发布