题意:Y和M要找一家KFC谈谈,求所用的最短时间,时间是根据走的步数决定的;
思路:搜搜搜啊,不过T了三发(忧桑,需要剪枝;
BFS+剪枝:剪枝方法:Y和M分别只有一个,但是"@"KFC却有很多;这样的话,我们可以从"Y"和"M"出发,记录所有的能到达Y和M的步数;
这样的话,只需要搜两遍图然后查询就可以了;
避免了每遇到一次'@'就要搜一次图的尴尬情况;
AC代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <queue> const int dx[4]= {0,0,-1,1}; const int dy[4]= {1,-1,0,0}; using namespace std; int n,m,vis[205][205],c1,c2,f1,f2; char s[205][205]; int dis1[210][210],dis2[210][210]; struct node { int a; int b; int sum; }; void bfs_M(int x,int y) { node ss; ss.a=x; ss.b=y; ss.sum=0; queue<node>q; q.push(ss); while(!q.empty()) { node xx=q.front(); q.pop(); for(int i=0; i<4; i++) { int kx=xx.a+dx[i]; int ky=xx.b+dy[i]; node k; k.a=kx; k.b=ky; k.sum=xx.sum+1; if(kx>=0&&kx<n&&ky>=0&&ky<m&&s[kx][ky]!='#'&&dis1[kx][ky]==0) { dis1[kx][ky]=k.sum; q.push(k); } } } return ; } void bfs_Y(int x,int y) { node ss; ss.a=x; ss.b=y; ss.sum=0; queue<node>q; q.push(ss); while(!q.empty()) { node xx=q.front(); q.pop(); for(int i=0; i<4; i++) { int kx=xx.a+dx[i]; int ky=xx.b+dy[i]; node k; k.a=kx; k.b=ky; k.sum=xx.sum+1; if(kx>=0&&kx<n&&ky>=0&&ky<m&&s[kx][ky]!='#'&&dis2[kx][ky]==0) { dis2[kx][ky]=k.sum; q.push(k); } } } return ; } int main() { int c,min1,rx,ry,ax,ay; while(~scanf("%d%d",&n,&m)) { memset(dis1,0,sizeof(dis1)); memset(dis2,0,sizeof(dis2)); for(int i=0; i<n; i++) { scanf("%s",s[i]); for(int j=0; j<m; j++) { if(s[i][j]=='Y') { rx=i; ry=j; } else if(s[i][j]=='M') { ax=i; ay=j; } } } bfs_Y(rx,ry);//搜两遍就好,能分别记录下"Y"和"M"到每个能够到达的地方的步数; bfs_M(ax,ay); min1=99999999; for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { if(s[i][j]=='@'&&dis1[i][j]>0&&dis2[i][j]>0) { min1=min(min1,dis1[i][j]+dis2[i][j]); } } } printf("%d ",min1*11); } return 0; }