这题目,唉,一开始以为很简单的,就是枚举每一个KFC到M和Y的距离,求出最短的,结果TLE了
之后,突然想到了双向搜索,天呐,又郁闷了很久,从来都没写过,一时不只从何下手,而且,不知道搜索时的停止条件该如果设置,结果就……
回到一开始最不想做的,就是分别用调用俩次BFS,算出M和Y到每一个KFC的最短距离,再累加求最短即可
这时候要注意,BFS退出的条件是遍历完所有的点,所以遇到‘@’时,把相应时间累加之后,还是要继续搜
另外,有一点也是十分重要的 ,就是未必每一个KFC都是可达的,所以要多加一步判断………唉………
#include<iostream> #include<string> #include<queue> using namespace std; int n,m,dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; char map[201][201]; bool vis[201][201]; struct node { int x,y,cnt; }f[2000]; //f[]用来记录每一个KFC的坐标 node f1,f2;//记录M和Y 的坐标 int a[201][201];//累加到达每一个KFC的时间 queue<node> Q; void bfs() { while(!Q.empty()) { node t=Q.front(),temp; Q.pop(); if(map[t.x][t.y]=='@') { a[t.x][t.y]+=t.cnt; } for(int k=0;k<4;k++) { int i=t.x+dir[k][0]; int j=t.y+dir[k][1]; if(i>n||i<1||j>m||j<1||vis[i][j]||map[i][j]=='#') continue; vis[i][j]=1; temp.x=i;temp.y=j;temp.cnt=t.cnt+1; Q.push(temp); } } return ; } int main() { int num; while(cin>>n>>m) { num=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>map[i][j]; if(map[i][j]=='M') { f1.x=i;f1.y=j; f1.cnt=0; } if(map[i][j]=='Y') { f2.x=i;f2.y=j; f2.cnt=0; } if(map[i][j]=='@') { f[num].x=i;f[num].y=j; num++; } } memset(a,0,sizeof(a));//这部分代码有点乱,不够和谐,但还是很清晰的 while(!Q.empty()) Q.pop(); memset(vis,0,sizeof(vis)); vis[f1.x][f1.y]=1; Q.push(f1); bfs( ); memset(vis,0,sizeof(vis)); while(!Q.empty()) Q.pop(); vis[f2.x][f2.y]=1; Q.push(f2); bfs( ); int max1=INT_MAX; for(int i=0;i<num;i++) { if(a[f[i].x][f[i].y]!=0&&a[f[i].x][f[i].y]<max1)//少了一个判断条件,多WA了几次 max1=a[f[i].x][f[i].y]; } cout<<max1*11<<endl; } return 0; }