bfs,放缩

hdoj 1428 漫步校园

先放缩,求出没点离终点的最短距离。然后从起点bfs求出总的路径数,或者记忆化搜索求路径数。

#include <iostream>
#include <queue>
using namespace std;

typedef __int64 lld;

struct Node {
	int x, y;
	Node() {}
	Node(int a, int b) { x = a; y = b; }
};

struct Node2 {
	int x, y;
	lld v;
};

bool operator<( Node2 n1, Node2 n2 ) {
	return n1.v < n2.v;
}

lld inf = (1<<30) - 1;
int n;
lld num[55][55], minDis[55][55], ans[55][55];

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

void input() {
	for( int i=0; i<n; ++i ) {
		for( int j=0; j<n; ++j ) {
			scanf( "%I64d", &num[i][j] );
		}
	}
}


bool isBond( Node q ) {
	if( q.x < 0 || q.y < 0 || q.x >= n || q.y >= n ) return 1;
	return 0;
}


//放缩,求出每点到终点的最短距离
void getEveryDis() {
	queue<Node> Q;
	Node p, q;
	bool mark[55][55];
	int i, j;
	for( i=0; i<n; ++i ) {
		for( j=0; j<n; ++j ) {
			minDis[i][j] = inf;
			mark[i][j] = 0;
		}
	}

	minDis[n-1][n-1] = num[n-1][n-1];
	p.x = p.y = n-1;
	Q.push( p );
	mark[p.x][p.y] = 1;
	while( !Q.empty() ) {
		p = Q.front();
		Q.pop();
		mark[p.x][p.y] = 0;
		for( i=0; i<4; ++i ) {
			q.x = p.x + dir[i][0];
			q.y = p.y + dir[i][1];
			if( isBond(q) ) continue;
			if( minDis[q.x][q.y] > minDis[p.x][p.y] + num[q.x][q.y]) {
				minDis[q.x][q.y] = minDis[p.x][p.y] + num[q.x][q.y];
				if( !mark[q.x][q.y] ) {
					Q.push( q );
					mark[q.x][q.y] = 1;
				}
			}
		}
	}
}


//记忆化搜索求路径数
lld dfs( Node p ) {
	int i;
	lld cnt = 0;
	Node q;
	if( p.x == n-1 && p.y == n-1 ) return 1;
	if( ans[p.x][p.y] != 0 ) return ans[p.x][p.y];
	for( i=0; i<4; ++i ) {
		q.x = p.x + dir[i][0];
		q.y = p.y + dir[i][1];
		if( isBond( q ) ) continue;
		if( minDis[q.x][q.y] >= minDis[p.x][p.y]) continue;
		cnt += dfs( q );
	}
	ans[p.x][p.y] = cnt;
	return cnt;
}

/*
//bfs求出结果
void solve() {
	int i, j;
	Node2 p, q;
	bool mark[55][55];
	priority_queue<Node2> Q;

	memset( ans, 0, sizeof(ans) );
	memset( mark, 0, sizeof(mark) );
	ans[0][0] = 1;
	p.x = p.y = 0;
	p.v = minDis[p.x][p.y];
	mark[p.x][p.y] = 1;
	Q.push( p );

	while( !Q.empty() ){
		p = Q.top();
		Q.pop();
		if( ans[p.x][p.y] > p.v ) p.v = ans[p.x][p.y];
		for( i=0; i<4; ++i ) {
			q.x = p.x + dir[i][0];
			q.y = p.y + dir[i][1];
			if( q.x < 0 || q.y < 0 || q.x >=n || q.y >= n )continue;
			if( minDis[q.x][q.y] >= minDis[p.x][p.y] ) continue;
			ans[q.x][q.y] += ans[p.x][p.y];
			q.v = minDis[q.x][q.y];
			if( !mark[q.x][q.y] ) {
				Q.push( q );
				mark[q.x][q.y] = 1;
			}
		}
	}
	printf( "%I64d\n", ans[n-1][n-1] );
			
}
*/


int main() {
//	freopen( "c:/aaa.txt", "r", stdin) ;
	while( scanf( "%d", &n ) ==  1 ) {
		input();
		getEveryDis();
		//solve();
		memset( ans, 0, sizeof(ans) );
		printf( "%I64d\n", dfs(Node(0, 0)) );
	}
	return 0;
}

.

posted on 2011-04-02 19:24  CrazyAC  阅读(163)  评论(0编辑  收藏  举报