您的位置:首页 > 其它

poj 3037 Skiing

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

本来打算昨天做完这题就开始下一个知识点的,但是前两天做一场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

;
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
);
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 ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: