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 ; }