/*
题意: 找出两点间的最长距离.
解题思路:
1. 树上面求最长路简单路(无环). 就是树的直径问题.
2. 树的直径问题经典: 两遍BFS即可.
问题分析:
(1). 一开始任取一个点u进行搜索查找出距离点u最远距离的点v和长度.
(2). 第二次BFS则从第一次中的点v找出距离点v最远距离的点的路径长度.
3. 问题正确性.
证明:
(1). 情况1: u在最长路上, 那么v一定是最长路的一端.
反证法: v不是在最长路的一端, 即有一个v1使得(u->v1)是最长路的一部分,
就有: dist(u->v1) > dist(u->v); 矛盾.
即: v在最长路的一端. (第二次BFS就可以找出距离v最远的点的长度.)
(2). 情况2: u不再最长路上, 则有点u到点v的路与最长路一定有一个交点c.
并且(c->v)与最长路的后半段是重合的. 即v一定是最长路的一端.
*/
# include <stdio.h>
# include <algorithm>
# include <iostream>
# include <queue>
# include <string.h>
using namespace std;
struct node
{
int x;
int y;
int step;
} ;
int vx[4]= {0,0,1,-1};
int vy[4]= {1,-1,0,0};
int n,m;
char a[1010][1010];
int vis[1010][1010];
int sum;
int judge(int tx,int ty)
{
if(tx>=0&&tx<n&&ty>=0&&ty<m)
return 1;
return 0;
}
node bfs(node a1)
{
int i;
node front,rear,ans;
memset(vis,0,sizeof(vis));
front.x=a1.x;
front.y=a1.y;
front.step=a1.step;
queue<node>q;
q.push(front);
vis[a1.x][a1.y]=1;
while(!q.empty())
{
front=q.front();
q.pop();
for(i=0; i<4; i++)
{
int xxx=front.x+vx[i];
int yyy=front.y+vy[i];
if(!vis[xxx][yyy]&&a[xxx][yyy]=='.'&&judge(xxx,yyy))
{
rear.x=xxx;
rear.y=yyy;
rear.step=front.step+1;
vis[xxx][yyy]=1;
q.push(rear);
}
}
}
return rear;
}
int main()
{
int i,j,flag;
node tt;
while(~scanf("%d%d",&m,&n))
{
for(i=0; i<n; i++)
{
getchar();
scanf("%s",a[i]);
}
for(i=0; i<n; i++)
{
flag=0;
for(j=0; j<m; j++)
{
if(a[i][j]=='.')
{
tt.x=i;
tt.y=j;
tt.step=0;
flag=1;
break;
}
}
if(flag)
break;
}
sum=0;
node ans=bfs(tt);
ans.step=0;
bfs(ans);
printf("%d\n",bfs(ans).step);
}
return 0;
}
URAL - 1145 Rope in the Labyrinth
最新推荐文章于 2015-12-26 10:02:00 发布