`
925695531
  • 浏览: 22449 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

poj3037 解题报告

 
阅读更多
这道题也是我拿来测板子的

题意:给定一个r*c(r<=100,c<=100)的矩阵,每个元素表示该点高度,给定初始速度v,当从一点移动到另一点后,速度变为原先的2^(该点高度-移动到的点的高度),花费时间是1/原先高度,求从1,1到r,c的最短时间

题解:可以推出,每个点速度是一样的,这样就直接最短路了

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
using namespace std ;

const int MAXN = 105 ;
const int MAXM = MAXN * MAXN * 20 ;
double INF = 9999999999.0 ;
double EPS = 0.000000001  ;

struct type
{
    int  end , next ;
    double length ;
} ;

type  edge[MAXM] ;
int   val[MAXN][MAXN]     ;
int   head[MAXN*MAXN]     ;
int   cnt[MAXN*MAXN]      ;
int   V , R , C , Count   ;
bool  vis[MAXN*MAXN]      ;
double  dis[MAXN*MAXN]    ;
double  speed[MAXN][MAXN] ;

int  dx[4] = { 0 , 0 , 1 , -1 } ;
int  dy[4] = { 1 , -1 , 0 , 0 } ;

void  addedge( int start , int end , double length )
{
    edge[Count].end    = end         ;
    edge[Count].length = length      ;
    edge[Count].next   = head[start] ;
    head[start]        = Count ++    ;
}

double SPFA( int start , int n )
{
	int  i ;
	memset( cnt , 0 , sizeof( cnt ) ) ;
	memset( vis , 0 , sizeof( vis ) ) ;
	for( i = 1 ; i <= n ; i ++ ) dis[i] = INF ;
	dis[start] = 0 ;
	queue < int > q ;
	q.push( start ) ; vis[start] = true ; ++ cnt[start] ;
	while( ! q.empty() )
	{
		int  u , v ;
		u = q.front() ;  q.pop() ;   vis[u] = false ;
		for( i = head[u] ; i != -1 ; i = edge[i].next ) {
			v = edge[i].end ;
			if( dis[v] > dis[u] + edge[i].length + EPS  )
			{
				dis[v] = dis[u] + edge[i].length ;
				if( !vis[v] ){
					q.push( v ) ;
					vis[v] = true ;
					if( ++cnt[v] > n ) return -1 ;
				}
			}
		}
	}
	return 0 ;
}

int  main()
{
    int  i , j , k ;

    memset( head  , -1 , sizeof( head  ) ) ;
    memset( vis   ,  0 , sizeof( vis   ) ) ;
    memset( speed , -1 , sizeof( speed ) ) ;
    Count = 0 ;

    scanf( "%d%d%d" , & V , & R , & C ) ;
    for( i = 0 ; i < R ; i ++ )
        for( j = 0 ; j < C ; j ++ )
            scanf( "%d" , & val[i][j] ) ;

    speed[0][0] = V ;
    for( i = 1 ; i < C ; i ++ )
        speed[0][i] = speed[0][i-1] * pow( 2 , double ( val[0][i-1] - val[0][i] ) )  ;
    for( i = 1 ; i < R ; i ++ )
        for( j = 0 ; j < C ; j ++ )
            speed[i][j] = speed[i-1][j] * pow( 2 , double ( val[i-1][j] - val[i][j] ) ) ;

    for( i = 0 ; i < R ; i ++ )
        for( j = 0 ; j < C ; j ++ )
            for( k = 0 ; k < 4 ; k ++ )
            {
                int tmpx = i + dx[k] ;
                int tmpy = j + dy[k] ;
                if( tmpx >= 0 && tmpx < R && tmpy >= 0 && tmpy < C )
                    addedge( ( i * C + j ) , ( tmpx * C + tmpy ) , 1.0 / speed[i][j] ) ;
            }
    SPFA( 0 , R * C ) ;
    printf( "%.2f\n" , dis[R * C - 1] ) ;
    return 0 ;
}

代码搓了点
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics