find a way
原题链接https://vjudge.net/contest/345248#problem/C
找到每个KFC的点算出两个人到KFC的距离之和,求最小值
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
long long n,m;
char ma[300][300];
long long visit[300][300];
long long book[300][300];
struct node
{
long long x;
long long y;
long long step;
} st,ed;
void bfs(long long sum)
{
long long i;
long long mv[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
memset(visit,0,sizeof(visit));
visit[st.x][st.y]=1;
queue<node>q;
q.push(st);
while(!q.empty())
{
st=q.front();
q.pop();
if(ma[st.x][st.y]=='@')//由sum来判断计算的是哪一个人的距离
{
if(sum==1)
{
book[st.x][st.y]=st.step;
}
else if(book[st.x][st.y]!=-1)//判断第一个人能否到达
{
book[st.x][st.y]+=st.step;
}
}
for(i=0; i<4; i++)//四个方向
{
ed.x=st.x+mv[i][0];
ed.y=st.y+mv[i][1];
if(visit[ed.x][ed.y]==0&&ma[ed.x][ed.y]!='#'&&ed.x>=0&&ed.y>=0&&ed.x<n&&ed.y<m)
{
ed.step=st.step+1;
q.push(ed);
visit[ed.x][ed.y]=1;
}
}
}
}
int main()
{
char c;
long long i,j,yy,yx,mx,my;
while(~scanf("%lld %lld",&n,&m))
{
memset(ma,0,sizeof(ma));
for(i=0; i<n; i++)
{
getchar();
for(j=0; j<m; j++)
{
scanf("%c",&c);
ma[i][j]=c;
if(c=='Y')//记录初始位置
{
yx=i;
yy=j;
}
else if(c=='M')
{
mx=i;
my=j;
}
}
}
memset(book,-1,sizeof(book));
st.x=yx;
st.y=yy;
st.step=0;
bfs(1);//第一个人
st.x=mx;
st.y=my;
st.step=0;
bfs(2);//第二个人
long long ans=0x3f3f3f3f;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(ma[i][j]=='@'&&book[i][j]!=-1&&visit[i][j]==1)//第二个人能否到达
{
ans=min(ans,book[i][j]);//取最小值
}
}
}
printf("%lld\n",ans*11);
}
return 0;
}