题目:http://acm.hdu.edu.cn/showproblem.php?pid=2612
一开始犯2了,每个kfc搜索一次m和y,剪了也TLE,后来看到别人的解题,说广搜得出m和y的步数图,找加起来最小的kfc就可以了
#include<stdio.h> int n,m; char map[300][300]; int sm[300][300]; int sy[300][300]; int mx,my,yx,yy; int kfc[50000][2]; int queue[50000]; int dx[4]={0,0,-1,1}; int dy[4]={1,-1,0,0}; void bfs(int x,int y,int z[300][300]) { int front=0,rear=0,u; u=x*m+y; queue[rear++]=u; while(front<rear) { u=queue[front++]; x=u/m; y=u%m; for(int d=0;d<4;d++) { int nx=x+dx[d]; int ny=y+dy[d];//printf("asdfsdfsdf\n"); if(nx>=0&&nx<n&&ny>=0&&ny<m&&map[nx][ny]!='#'&&z[nx][ny]==0) { int v=nx*m+ny; queue[rear++]=v; z[nx][ny]=z[x][y]+1; } } } } int main() { while(scanf("%d %d",&n,&m)!=EOF) { int i; int j; int count=0; for(i=0;i<n;i++) for(j=0;j<m;j++) { sm[i][j]=0; sy[i][j]=0; } getchar(); for(i=0;i<n;i++) { for(j=0;j<m;j++) { scanf("%c",&map[i][j]); if(map[i][j]=='M') { mx=i; my=j; } if(map[i][j]=='Y') { yx=i; yy=j; } if(map[i][j]=='@') { kfc[count][0]=i; kfc[count++][1]=j; } } getchar(); } bfs(mx,my,sm); bfs(yx,yy,sy); int min=50000; for(i=0;i<count;i++) { int x=kfc[i][0]; int y=kfc[i][1]; if(sm[x][y]&&sy[x][y]&&sm[x][y]+sy[x][y]<min) min=sm[x][y]+sy[x][y]; } printf("%d\n",min*11); } return 0; }