http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=15717
思路就是 2次BFS,
第一次Y出发 走遍所有的点 并把到每一个点的最短路记录 (结构体)
第二次M出发 做同样的事、
然后把所有@KFC 点 遍历 找到看 Y到@和M到@之和 的最小值
需要注意的是。。如果有对某一个@ 两人都找不到路去。。那么 bfs得到的结果会是0+0=0 但是显然不对
所以在 最后遍历求最小和的步骤 要加上一个判断 两个ans1 ans2 都不等于0
、、
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <iostream> #include <queue> #include <set> #include <vector> using namespace std; struct node { int x,y; int time; }; int n,m; queue<node> qq; char tm[205][205]; char vis[205][205]; int kfc[2005][2]; int ans1[505][505]; int ans2[505][505]; int ans[505][505][3]; int dir[][2]={0,-1, 0,1, -1,0, 1,0}; //方向数组 int y11,y2; int m1,m2; int bfs(int f,int c) { while(!qq.empty()) qq.pop(); int i; node tmp; tmp.x=f; tmp.y=c; tmp.time=0; qq.push(tmp); vis[f][c]=1; while(!qq.empty()) { node t=qq.front(); qq.pop(); node k=t; for (i=0;i<4;i++) { t=k; t.x+=dir[i][0]; t.y+=dir[i][1]; if ((tm[t.x][t.y]=='.'||tm[t.x][t.y]=='@')&&vis[t.x][t.y]==0&& t.x>=1 &&t.y<=m&&t.y>=1&&t.x<=n) { vis[t.x][t.y]=1; t.time++; // if (tm[t.x][t.y]=='@') { if ( f==y11 && c==y2 ) { ans[t.x][t.y][0]=t.time; } else { ans[t.x][t.y][1]=t.time; } } qq.push(t); } } } return 0; } int main() { int i,j; // memset(ans,0,sizeof(ans)); while(scanf("%d%d",&n,&m)!=EOF) { getchar(); int ok=0; for (i=1;i<=n;i++) { for (j=1;j<=m;j++) { scanf("%c",&tm[i][j]); if (tm[i][j]=='Y') { y11=i; y2=j; } if (tm[i][j]=='M') { m1=i; m2=j; } if (tm[i][j]=='@') { kfc[++ok][0]=i; kfc[ok][1]=j; } } getchar(); } int max=0x7f7f7f7f; int h; memset(vis,0,sizeof(vis)); bfs(y11,y2); memset(vis,0,sizeof(vis)); bfs(m1,m2); for (h=1;h<=ok;h++) { int q1=kfc[h][0]; int q2=kfc[h][1]; // cout<<ans[q1][q2][0]<<" "<<ans[q1][q2][1]<<endl; if (ans [q1][q2][0]!=0&&ans [q1][q2][1]!=0) //千万注意要确保都全为零。即排除找不到路的情况。找不到路是ans=0,但不是最短 max=__min(ans[q1][q2][0]+ans[q1][q2][1],max); // max=__min(ans[q1][q2][0]+ans[q1][q2][1],max); } __int64 ans=max*11; printf("%I64d\n",ans); } return 0; }