题目:给定平面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
原文:http://blog.csdn.net/mobius_strip/article/details/21336855