糯米

TI DaVinci, gstreamer, ffmpeg
随笔 - 167, 文章 - 0, 评论 - 47, 引用 - 0
数据加载中……

POJ 3039 Skiing 单源最短路径

这题看起来很屌。
但是实际上走到每个点之后,速度必然是当前点和左上角点的差值的倒数。
所以,每个点到其他点的所花费的时间都是这个点自己的值决定的。
而且没可能经过一个点两次的,因为经过两次肯定是浪费时间的。
问题就变成了求最短路径。

注意:
这题的精度很莫名其妙,用C++可以AC的,G++、GCC都是WA。
不能用整数来保存时间,虽然看上去位数是够用的,但是遇到比较屌的数据就挂了。
就在这个问题上杯具了很久。

#include <stdio.h>
#include 
<math.h>

#ifndef _countof
#define _countof(x) (sizeof(x)/sizeof(x[0]))
#endif

#define SIZE 128

int map[SIZE][SIZE], R, C, V;
double D[SIZE][SIZE], _tbl[128], *tbl = &_tbl[64];
int queue[65536][2], head, tail;
int vis[SIZE][SIZE];

inline 
void push(int y, int x, double d)
{
    
if (y < 0 || y >= R || x < 0 || x >= C)
        
return ;
    
if (d > D[y][x])
        
return ;
    D[y][x] 
= d;
    
if (vis[y][x])
        
return ;
    vis[y][x] 
= 1;
    queue[tail][
0= y;
    queue[tail][
1= x;
    tail
++;
    tail 
&= _countof(queue) - 1;
}


inline 
void pop(int *y, int *x)
{
    
*= queue[head][0];
    
*= queue[head][1];
    head
++;
    head 
&= _countof(queue) - 1;
    vis[
*y][*x] = 0;
}


int main()
{
    
int i, j;
    
double d;

    freopen(
"e:\\test\\in.txt""r", stdin);

    
for (i = -64; i <= 64; i++)
        tbl[i] 
= pow(2.0, i);

    scanf(
"%d%d%d"&V, &R, &C);
    
for (i = 0; i < R; i++{
        
for (j = 0; j < C; j++{
            scanf(
"%d"&map[i][j]);
            
if (i || j)
                map[i][j] 
-= map[0][0];
            D[i][j] 
= 1e80;
        }

    }

    map[
0][0= 0;

    push(
000); 
    
while (head != tail) {
        pop(
&i, &j);
        d 
= D[i][j] + tbl[map[i][j]];
        push(i 
+ 1, j, d);
        push(i 
- 1, j, d);
        push(i, j 
+ 1, d);
        push(i, j 
- 1, d);
    }


    printf(
"%.2lf\n", D[R - 1][C - 1/ V);
    
    
return 0;
}

posted on 2010-04-12 16:45 糯米 阅读(461) 评论(0)  编辑 收藏 引用 所属分类: POJ


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理