zoj 1891

22 篇文章 0 订阅
/*
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值