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;
}