首页 > 其他 > 详细

UVa 929 - Number Maze

时间:2014-03-16 21:37:28      阅读:551      评论:0      收藏:0      [点我收藏+]

题目:给定平面N*M的网格,每个里面有一个0-9的某个数字。求左上到右下的路径和最小,每次走相邻格。

分析:最短路。dijkstra+优先队列险过。尝试了各种算法,bellman-ford算法TLE,spfa+stack算法TLE。

注意:很卡常系数,o(╯□╰)o;采取一维状态记录TLE,利用二维状态记录可提高效率。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>

using namespace std;

int maze[1000][1000];
int value[1000][1000];
int visit[1000][1000];
int d[4][2] = {0,1,0,-1,1,0,-1,0};

//banery_heap
#define cmpdef <

int  keys[1000000];
int  base[1000000];
int  In_h[1000000];

class banery_heap
{
private:
	int  size;
public:
	banery_heap( int count = 1000000 ) {
		size = 0;
		memset( base, 0, sizeof( base ) );
		memset( keys, 0, sizeof( keys ) );
		memset( In_h, 0, sizeof( In_h ) );
	}
	bool empty(){return size == 0;}
	void Insert( int ID, int Key ) {
		if ( !In_h[ID] ) {
			In_h[ID] = ++ size;
			base[size] = ID;
		}
		keys[In_h[ID]] = Key;
		int now = In_h[ID];
		while ( now > 1 && keys[now] cmpdef keys[now>>1] ) {
			swap( base[now], base[now>>1] );
			swap( keys[now], keys[now>>1] );
			swap( In_h[base[now]], In_h[base[now>>1]] );
			now = now>>1;
		}
	}
	int Delete( void ) {
		swap( base[size], base[1] );
		swap( keys[size], keys[1] );
		swap( In_h[base[size]], In_h[base[1]] );
		int now = 1;
		while ( 1 ) {
			int New = now,L = (now<<1),R = (now<<1)+1;
			if ( L < size && keys[L] cmpdef keys[New] ) New = L;
			if ( R < size && keys[R] cmpdef keys[New] ) New = R;
			if ( now == New ) break;
			swap( base[now], base[New] );
			swap( keys[now], keys[New] );
			swap( In_h[base[now]], In_h[base[New]] );
			now = New;
		}
		return base[size --];
	}
};
//end banery_heap

int dijkstra( int N, int M )
{
	for ( int i = 0 ; i < N ; ++ i )
	for ( int j = 0 ; j < M ; ++ j ) {
		value[i][j] = 10000000;
		visit[i][j] = 0;
	}
	
	banery_heap Heap;
	Heap.Insert( 0, value[0][0] = maze[0][0] );
	while ( !Heap.empty() ) {
		int id = Heap.Delete();
		visit[id/1000][id%1000] = 1;
		for ( int i = 0 ; i < 4 ; ++ i ) {
			int x = id/1000+d[i][0];
			int y = id%1000+d[i][1];
			if ( x >= 0 && x < N && y >= 0 && y < M && !visit[x][y] )
			if ( value[x][y] > value[id/1000][id%1000] + maze[x][y] ) {
				value[x][y] = value[id/1000][id%1000] + maze[x][y];
				Heap.Insert( x*1000+y, value[x][y] );
			}
		}
	}
	return value[N-1][M-1];
}

int main()
{
	int T,N,M;
	while ( scanf("%d",&T) != EOF )
	while ( T -- ) {
		scanf("%d%d",&N,&M);
		for ( int i = 0 ; i < N ; ++ i )
		for ( int j = 0 ; j < M ; ++ j )
			scanf("%d",&maze[i][j]);
			
		printf("%d\n",dijkstra( N, M ));
	}
	return 0;
}

UVa 929 - Number Maze,布布扣,bubuko.com

UVa 929 - Number Maze

原文:http://blog.csdn.net/mobius_strip/article/details/21336855

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!