poj 3037 Skiing

困啊!!不知道学校怎么想的,一声令下就要每天开始晨练,由于消息来得过于突然,导致的后果就是,食堂吃饭的人剧增,去的晚了点差点没吃上饭;起得太早没睡好,上课浑浑噩噩的,唉,今天还是早点睡吧。。。。。

本来打算昨天做完这题就开始下一个知识点的,但是前两天做一场CF,里面有两道数论题,当时没做出来,昨天就做了做,所以推到了今天。

题意:给出一个R*C的矩阵,每个矩阵的点都有一个海拔高,开始有一个初始速度V,然后每个点的速度是V*2^(h[1] - h[i] ),所花费的时间是速度的倒数,求从左上角的点到右下角的点的最少时间。

思路:从公式可以得出,要从a->b->c,则c出发的速度就是V*2^(A-B)*2^(B-C)=V*2^(A-C),所以每个点的速度都是恒定的,每个点的时间也就确定了,然后就是求最短路了。。。。。。不解释了。。。。。

代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <queue>
#define  N 104
using namespace std ;

const double INF = 999999999999.99 ;//这里INF要足够大!

struct node
{
    int e ;
    double tim ;
    int next ;
}p[4*N*N] ;

int head[N*N] , map[N][N] ;
double dis[N*N] ;
bool vist[N*N] ;
int v ,  n , num ;

void add( int x , int y , double t )
{
    p[num].e = y ;
    p[num].tim = 1.0 / t ;
    p[num].next = head[x] ;
    head[x] = num++ ;
}

void Spfa()
{
    int u , v ;
    queue<int>q ;

    while ( !q.empty()) q.pop();
    q.push ( 1 ) ;
    dis[1] = 0 ;

    while ( !q.empty())
    {
        u = q.front();
        q.pop();
        vist[u] = false ;

        for ( int i = head[u] ; i != -1 ; i = p[i].next )
        {
            v = p[i].e  ;
            if ( dis[v] > dis[u] + p[i].tim )
            {
                dis[v] = dis[u] + p[i].tim ;
                if ( !vist[v] )
                {
                    vist[v] = true ;
                    q.push ( v ) ;
                }
            }
        }
    }

    printf( "%.2lf\n" , dis[n] );
    return  ;
}

int main()
{
    int i , j , r , c , x ;
    double tem ;

    while ( scanf ( "%d%d%d" , &v , &r , &c ) != EOF )
    {
        n = r * c ;
        for ( i = 1 ; i <= r ; i++ )
        for ( j = 1 ; j <= c ; j++ )
        {
            scanf ( "%d" , &map[i][j] );
        }

        memset( head , -1 , sizeof ( head )) ;
        num = 0 ;
        for ( i = 1 ; i <= r ; i++ )
        for ( j = 1 ; j <= c ; j++ )
        {
            x = ( i - 1 ) * c + j ;
            tem = v * pow ( 2.0 , map[1][1] - map[i][j] );//由于忘了乘上V,WA了两次,警告一下自己,要细心!
            dis[x] = INF ;
            vist[x] = false ;
            
            if ( j - 1 > 0 )
            add ( x , x - 1 , tem ) ;
            if ( j + 1 <= c )
            add ( x , x + 1 , tem ) ;
            if ( i > 1 )
            add ( x , x - c , tem ) ;
            if ( i < n )
            add ( x , x + c , tem ) ;
        }
        Spfa();
    }
    return 0 ;
}

 

原文地址:https://www.cnblogs.com/misty1/p/2736340.html