Poj 1383 Labyrinth( 搜索获得全局最短路径 )

http://poj.org/problem?id=1383
题目大意:
        在图中找出距离最远的两点间的距离。
        题目给出的图类似如下:( '#'代表障碍物, '.'代表可以通行的路 )
         #######
         #.#.###
         #.#.###
         #.#.#.#
         #.....#
         #######
本题思路:
        这题暴力枚举每一点出发的最长路径显然不可行。
        可以先在纸上模拟一下。从任意点A出发的最长路径的另一个端点称为B,我们或许可以发 `                                                现 B就是全局最长路径的一个端点。接下来问题就很简单了,只要从B点开始搜索一遍图,就可以找到全局最长路径了。
        这题的关键就是证明以上红色标注的文字成立。只要证明成立,那么这道题就可以用两次搜                            索解决。以下是我自己给出的简短证明,如有证明不当之处请路人指出。

证明以上红色标注的文字成立:
                                    
         假设:A为搜索起点,L[AB]为从A出发的最长路,B为该路径的另一端点。
         待证明的问题是 : B一定是全局最长路的一个端点
        根据搜索起点A的不同分两种情况证明。
        (一). A为全局最长路的一个端点。
                该情况下显然L[AB]即为全局最长路,即B为全局最长路的另一个端点。
        (二).A为非全局最长路端点的任意端点。
        反证法:
                    1).设点B不是全局最长路的端点。
                    2).则一定存在一条全局最长路,设它的端点为C,D。
                     3).由2)得,l3 < min { l1l2 }。(因为若l3>l1,则L[BD]就成为全局最长路了.)
                     4).由3)得 , min{ L[AC], L[AD] }>L[AB]。
                    5).这与假设相矛盾, 即L[AB]不是从A出发的最长路。
                    6).因此B一定是全局最长路的一个端点。
                    7).证毕。

程序代码:
#include <iostream>
using namespace std;
const int N = 1000;
const int Max = 5 * 100000;
const int Dir[4][2] = { {0, -1}, 
						{0,  1},
						{-1, 0},
						{1,  0} };

//-------------------------- Object --------------------------//
/* graph */
char g[N][N];
int R, C;
/* state struct */
struct State 
{
	int p;   // point
	int len; // length
}Q[Max];	 // queue
int front, rear; // queue pointer
/* max length and the farest point */
int maxLen, farPoint;
//------------------------- Function -------------------------//
/*
*	Queue Operations
*/

void InitQueue()
{
	front = rear = 0;
}

void Push( const int p, const int len )
{
	Q[rear].p = p;
	Q[rear].len = len;
	++ rear;
}

State Pop()
{
	State top = Q[ front++ ];
	return top;
}

bool IsEmpty()
{
	return front == rear;
}

/*
*	end of Queue
*/

bool IsInMap( const int r, const int c )
{
	return r >= 0 && r < R && c >= 0 && c < C;  
}

/*
*	BFS:get a lenghest path from startPoint
*/
void BFS( const int startPoint, const char white, const char gray )
{
	// push initial state into queue
	Push( startPoint, 1 );
	g[ startPoint/C ][ startPoint%C ] = gray;
	maxLen = 1, farPoint = startPoint;

	// BFS
	while( !IsEmpty() )
	{
		/* get queue top */
		State top = Pop();
		/* spread child state */
		for( int i = 0; i < 4; ++ i ) {
			int r = top.p/C + Dir[i][0];
			int c = top.p%C + Dir[i][1];
			if( !IsInMap(r, c) ) continue;
			if( g[r][c] == white ) {	/* spread to child state */
				Push( r*C+c, top.len+1 );
				g[r][c] = gray;
				if( top.len + 1 > maxLen ) {
					maxLen = top.len + 1;
					farPoint = r*C+c;
				}
			}// if
		}// for
	}// while
}


int main()
{
	freopen( "1.txt", "r", stdin );
	int T;
	scanf( "%d", & T );
	while( T -- )
	{
		int sp;
		scanf( "%d%d", & C, & R );				/* input graph */
		for( int r = 0; r < R; ++ r )
		{
			getchar();
			scanf( "%s", g[r] );
		}
		for( int i = 0; i < R * C; ++ i )		/* get start point */
			if( g[i/C][i%C] == '.' ) {
				sp = i;
				break;
			}

		InitQueue();							/* first BFS */
		BFS( sp, '.', '_' );
		/*printf( "%d\n", farPoint );

		for( int i = 0; i < C; ++ i )
		{
			printf( "%s\n", g[i] );
		}*/

		InitQueue();							/* second BFS */
		BFS( farPoint, '_', '.' );
		/*printf( "%d\n", farPoint );

		for( int i = 0; i < C; ++ i )
		{
			printf( "%s\n", g[i] );
		}*/
		printf( "Maximum rope length is %d.\n", maxLen - 1 );
	}
	system( "pause" );
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值