poj1124 Oh, Those Achin' Feet dfs+bfs最短路

26 篇文章 0 订阅
13 篇文章 0 订阅
Oh, Those Achin' Feet
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 490 Accepted: 131

Description

In recent days, a number of people have been injured after being pushed off the sidewalks due to overcrowding. City Hall is interested in figuring out how much pedestrian traffic its sidewalks receive every day. The results of this study will be used to determine whether the city needs to fund more sidewalks. The city has surveyed various buildings in several blocks to determine the traffic patterns they generate. Your job is to take this survey data and convert it into sidewalk utilization information.

Your program will read in the size of the map and a map of several city blocks. Buildings, streets, and building entrance/exits will be marked on the map. You will also be given a list of pedestrian load between several pairs of exits and entrances. Your program will determine the paths used by pedestrians between each source and destination, add up the total pedestrian load from all paths using each street, and output a table of the total pedestrian load on each square.

Notes:

  • The map is divided into squares. Each square of the map can be a street square, a building square, or an entrance/exit square. An entrance/exit square serves as both entrance and exit for that building. There will be no more than 90 street squares in the map.

  • People will always follow the shortest path between their origin and destination. No shortest path will exceed 75 squares.

  • If there are multiple equal-length shortest paths, the load will be divided equally amongst the paths. For shortest paths, there will be fewer than 50000 equallength path combinations.

  • If a building entrance/exit has multiple sides facing a street (for example, a corner of a building), the pedestrians may enter or exit through any street-facing side.

  • All movement will be strictly N, E, S, or W. No diagonal movement is permitted.

  • Pedestrians cannot move through buildings or off the edge of the map.

  • For convenience, you may ignore the fact that each street section may have two sidewalks.

  • Traffic load is not applied to the actual exit/entrance squares themselves.

  • If an origin and destination are adjacent on the map, pedestrians may move directly between them. In this case, there is no resulting load placed on any portion of the map because no streets are used.

Input

Line 1: X Y
X is the number of columns in the map, Y is the number of rows. Each is a positive integer less than 20.

Line 2-(Y+1):
Each line contains exactly X symbols indicating the contents of that square on the map. The symbols are:
X: building, non-entrance/exit
.: (period) street
{A-O}: letter indicating exit/entrance. Each letter may occur at most once.

Lines (Y+2)-?:
Each line indicates a pedestrian route and specifies a source, destination, and pedestrian load. Source and destination will each be a letter {A-O} with no spaces in between. The load factor will be a nonnegative integer, separated from the destination by whitespace. Source and destination will never be equal. At most 25 routes will be given. There will be a valid path in the map for each requested route.

The file will terminate with the line:
XX 0

Output

The output consists of Y lines, each with X space-separated fields indicating the load factor. Each load factor is printed to two decimal places with 4 spaces for integer digits (C 7.2 format).

Sample Input

4 4 
.... 
A.X. 
XXX. 
B... 
AB 2 
BA 1 
XX 0 

Sample Output

   1.50   3.00   3.00   3.00 
   0.00   1.50   0.00   3.00 
   0.00   0.00   0.00   3.00 
   0.00   3.00   3.00   3.00 

Source

思路: bfs求最短路径长度ibest,dfs找出所有长度为ibest的最短路,并且用sum数组把所有ibest的最短路负荷加起来。等搜索结束num条长度为ibest的最短路,都除以num即可。
注意事项:1. 建筑物不能走(wa点)
                  2. 输出用f不用lf  (wa点)
                  3.格式7.2f (PE)

还有就是谁在zoj上的1055这题过了可以发我下吗?我死活过不了,PE无数次,始终不知道它的格式是什么。
关于奇偶剪枝:http://blog.csdn.net/frankax/article/details/79102699

Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <queue>
#include <math.h>
#include <cstdlib>
#include <cmath>
using namespace std;
const int AX = 30 + 6;
const int maxn = 5e5;
char G[AX][AX];
int vis[AX][AX];
int oddEven[AX][AX];  //剪枝
int ibest;
double sum[AX][AX];
double res[AX][AX];
int n, m ; 
int dir[4][2] = {
	{1,0},
	{-1,0},
	{0,-1},
	{0,1}
};
struct Node
{	
	int x, y ;
	int step;
} q, pos ;

void bfs( Node s , Node e ){   
	queue<Node> que;
	s.step = 0;
	que.push(s);
	vis[s.x][s.y] = 1;
	ibest = -1;
	while( !que.empty() ){
		q = que.front();
		que.pop();
		if( q.x == e.x && q.y == e.y ){ 
			ibest = q.step;
			return;
		}
		for( int i = 0 ; i < 4 ; i++ ){
			int xx = q.x + dir[i][0];
			int yy = q.y + dir[i][1];
			if( xx >= 0 && xx < m && yy >= 0 && yy < n && G[xx][yy] != 'X'
				&& !vis[xx][yy]	){
				pos.x = xx ; pos.y = yy ; pos.step = q.step + 1;
			que.push(pos);
			vis[xx][yy] = 1;
		}
	}
}
return ;
}
stack<Node> sb;
stack<Node> sb_copy;
int num ;
void dfs( int x , int y , int val, int len , Node s , Node e ){
	if( num >= maxn ) return;
	if( len > ibest ) return ;
	if( G[x][y] >= 'A' && G[x][y] <= 'Z' ){   //建筑物不能走
		if( x == s.x && y == s.y ) {}
			else if( x == e.x && y == e.y ){
				if( len == ibest ){
					num ++ ;
					while( sb.size() ){
						sb_copy.push(sb.top());
						sb.pop();
					}
					Node tmp;
					while( sb_copy.size() ){
						tmp = sb_copy.top();
						if( tmp.x >= 0 && tmp.x < m && tmp.y >= 0 && tmp.y < n){
							sum[tmp.x][tmp.y] += (double) ( val );
							sb.push(tmp);
						}
						sb_copy.pop();
					}
				}
				return ;
			}else{
				return ;
			}
		}

		if (  ((ibest-len) % 2) != ( abs(oddEven[x][y]-oddEven[e.x][e.y]) % 2 ) ){  //奇偶剪枝
			return ;
		}

		for( int i = 0 ; i < 4 ; i++ ){
			int xx = x + dir[i][0];
			int yy = y + dir[i][1];
			if( xx >= 0 && xx < m && yy >= 0 && yy < n && G[xx][yy] != 'X'
				&& !vis[xx][yy] ){
				Node tmp;
			tmp.x = xx; tmp.y = yy; 
			sb.push(tmp);
			vis[xx][yy] = 1;
			dfs( xx , yy , val, len + 1 , s , e );
			sb.pop();
			vis[xx][yy] = 0;
		}
	}
}

int main(){
	scanf("%d%d",&n,&m);
	for( int i = 0 ;i < m ; i++ ){
		scanf("%s",G[i]);
	}
	char op[10]; int t ;
	      //奇偶剪枝数组初始化        TE的话就加上这个
	for ( int i = 0; i < m; i ++ ){
		if ( i % 2 ){
			for (int j = 0; j < n; j ++ ){
				if ( j % 2 == 1){
					oddEven[i][j] = 1;
				}else{
					oddEven[i][j] = 0;
				}
			}
		}else{
			for (int j = 0; j < n; j ++ ){
				if ( j % 2 == 1 ){
					oddEven[i][j] = 0;
				}else{
					oddEven[i][j] = 1;
				}
			}
		}
	}

	while( scanf("%s%d",op,&t) ){
		memset( sum , 0.00 , sizeof(sum));
		memset(vis,0,sizeof(vis));
		if( !t ) break;
		Node s , e;
		for( int i = 0 ; i < m ; i ++ ){
			for( int j = 0 ; j < n ; j ++ ){
				if( G[i][j] == op[0] ){
					s.x = i ; s.y = j;
				}
				else if( G[i][j] == op[1] ){
					e.x = i ; e.y = j;
				}
			}
		}
		if( (abs(s.x - e.x) == 1 && s.y == e.y) || ( abs(s.y-e.y) == 1 && s.x == e.x ) ){

		}else{

		//cout << s.x << ' ' << s.y << endl;
			bfs( s , e );
			num = 0;
			memset(vis,0,sizeof(vis));
			memset(sum,0.00,sizeof(sum));
			vis[s.x][s.y] = 1;
			while( sb.size() ) sb.pop();
			while( sb_copy.size() ) sb_copy.pop();
			dfs( s.x , s.y , t , 0 , s , e);

			for( int i = 0 ; i < m ; i++ ){
				for( int j = 0 ; j < n ; j++ ){
					res[i][j] += double( sum[i][j] / num );
				}
			}
		}

	}
	double tmp = 0.00;
	for( int i = 0 ; i < m ; i ++ ){
		for( int j = 0 ; j < n ;j ++ ){
			if( G[i][j] == '.' ) printf("%7.2f",(double)res[i][j]);
			else  printf("%7.2f",tmp);
		}
		cout << endl;
	}
	cout << endl;
	return 0;	
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值