您的位置:首页 > 其它

HDU 2612 Find a way(两次BFS)

2013-08-02 13:13 429 查看
题意:有两个人Y和M,给你一个n*m的矩阵。'.'是道路,'Y'是Y的位置,'M'是M的位置,'#'是不能走的路,'@'是KFC。(Y始终在左上角)现在两个人要到城里的一个KFC碰面,问你所需要花费的最短时间是多少。

思路:如果直接从Y搜索到M由于必须经过一个KFC显然不可取,因此转化思路。从Y出发搜索到所有KFC的距离,再从M出发搜索到所有KFC的距离,最后枚举找出一个KFC到两个距离和最短即可。

注意:KFC也是可以走的,而Y和M不能走要看做障碍。

在这个题中学会了求BFS的深度:设h[i]为当前节点的深度,x为点i的父亲节点,则h[i]=h[x]+1,设开始BFS的节点h[]=0即可。(还是太弱了啊)

附AC代码:

#include<stdio.h>
int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};//上下左右
struct node
{
int x,y,z;//z代表当前深度
//若点x的父亲节点是y,则x.z=y.z+1
};
node q[40000+10];
int n,m;
char map[200+10][200+10],mark[210][210];
int sum1[210][210],sum2[210][210];//Y和M分别到各个KFC的距离

void bfs(int xx,int yy,int zz[210][210])
{
int i,j,k,front=0,rear=1;
q[front].x=xx,q[front].y=yy,q[front].z=1;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
mark[i][j]=map[i][j];
while(front<rear)
{
for(int i=0;i<4;i++)//统计四种路径
{
int a=q[front].x+dx[i],b=q[front].y+dy[i];
if(a>=0&&b>=0&&a<n&&b<m&&mark[a][b]!='#'&&mark[a][b]!='Y'&&mark[a][b]!='M')//Y和M所在的地点是不能走的
{
q[rear].x=a,q[rear].y=b,q[rear].z=q[front].z+1;
rear++;//当前节点入队
}
else
continue;
if(mark[a][b]=='@')//若当前位置为KFC,则保存路径长度并更改标记
{
zz[a][b]=q[rear-1].z;
mark[a][b]='#';
}
else
mark[a][b]='#';
}
front++;
}
}

int main()
{
int count;//统计KFC的个数
int i,j,k;
node Y,M,KFC[40000+10];//运用结构体数组Y,M,KFC储存Y,M和各个KFC的坐标
while(scanf("%d%d",&n,&m)!=EOF)
{
count=0;
for(i=0;i<n;i++)
scanf("%s",map[i]);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
if(map[i][j]=='Y')
Y.x=i,Y.y=j;
else if(map[i][j]=='M')
M.x=i,M.y=j;
else if(map[i][j]=='@')//KFC
{
KFC[count].x=i,KFC[count].y=j,count++;
sum1[i][j]=999999,sum2[i][j]=999999;//sum1和sum2数组记录KFC(i,j)到Y和M距离
}
}
bfs(Y.x,Y.y,sum1),bfs(M.x,M.y,sum2);
int ans=99999999;
for(i=0;i<count;i++)//依次枚举各个KFC,取到Y和M距离和最短的KFC
if(sum1[KFC[i].x][KFC[i].y]+sum2[KFC[i].x][KFC[i].y]<ans)
ans=sum1[KFC[i].x][KFC[i].y]+sum2[KFC[i].x][KFC[i].y];
printf("%d\n",(ans-2)*11);//ans多加了两次2
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: