Sicily 1321. Robot

Dijkstra算法,但是由于是网格的缘故,在寻找最短路径时很费时,直接使用会TLE,必须使用优先队列才可以AC。另外也可以用宽搜,但要保证路程必须是最短的 (以往宽搜一般是访问过就不访问了,而在这里用,若新的访问能够使得访问该点的路程变短的话,就必须重新访问)。鉴于宽搜必须全部访问完毕才能够得到最优结果,不同于利用贪心算法的Dijkstra算法可以保证每个子过程都是最优的,所以宽搜不能因为目标节点被访问过就输出结果,而Dijkstra却可以。所以在这点上Dijkstra更有优势。

Run Time: 0.01sec

Run Memory: 304KB

Code length: 1573Bytes

SubmitTime: 2012-01-06 16:52:20

// Problem#: 1321
// Submission#: 1177427
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;

struct Path {
    int i, j;
    int dist;
    Path( int a, int b, int c ) { i = a; j = b; dist = c; }
    friend bool operator < ( const Path &p1, const Path &p2 ) { return p1.dist > p2.dist; }
};

int dirt[ 4 ][ 2 ] = { { -1, 0 }, { 0, 1 }, { 1, 0 }, { 0, -1 } };

int main()
{
    int T;
    int row, column;
    int si, sj, ti, tj;
    int i, j, k;
    int grid[ 101 ][ 101 ];
    bool included[ 101 ][ 101 ];

    scanf( "%d", &T );
    while ( T-- ) {
        priority_queue<Path> q;
        scanf( "%d%d", &row, &column );
        for ( i = 1; i <= row; i++ ) {
            for ( j = 1; j <= column; j++ )
                scanf( "%d", &grid[ i ][ j ] );
        }   
        scanf( "%d%d%d%d", &si, &sj, &ti, &tj );

        memset( included, false, sizeof( included ) );
        included[ si ][ sj ] = true;
        Path add = Path( si, sj, grid[ si ][ sj ] );
        while ( !included[ ti ][ tj ] ) {
            for ( k = 0; k < 4; k++ ) {
                i = add.i + dirt[ k ][ 0 ];
                j = add.j + dirt[ k ][ 1 ];
                if ( i >= 1 && i <= row && j >= 1 && j <= column && !included[ i ][ j ] ) {
                    q.push( Path( i, j, add.dist + grid[ i ][ j ] ) );
                }
            }

            add = q.top();
            while ( included[ add.i ][ add.j ] ) {
                q.pop();
                add = q.top();
            }
            included[ add.i ][ add.j ] = true;
        }
        printf( "%d\n",add.dist );
    }

    return 0;

}                                 


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值