P5195 [USACO05DEC]Knights of Ni S——BFS最短路
思路
题目要求的是从公主出发,途径4到达骑士位置的最小距离,那么不妨转换一下,从骑士和公主处分别出发,到达‘4’的最小距离
显然我们可以分别以公主和骑士为源点进行\(bfs\)
以公主为源点的距离记为\(dist1\)
以骑士为源点的距离记为\(dist2\)
然后我们枚举一下到哪个'4'点汇聚就行了,
时间复杂度\(O(n^2)\)
一个大大的优化\(TLE--->AC\)
if(vis2[t.x][t.y])continue;
vis2[t.x][t.y]=1;
如果当前点已经拓展过了,直接跳出,没有再进行拓展的必要了
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1001;
char mapp[N][N];
int W,H;
int dx[5]= {1,0,-1,0};
int dy[5]= {0,1,0,-1};
struct node
{
int x,y;
};
queue<node> q;
bool vis1[N][N],vis2[N][N];
int dist2[N][N],dist1[N][N];
int quex,quey;
int horx,hory;
struct n
{
int x,y;
} qq[1000020];
int hh;
inline void bfs1(int x,int y)
{
dist1[x][y]=0;
q.push((node)
{
x,y
});
while(q.size())
{
node t=q.front();
q.pop();
if(vis1[t.x][t.y])continue;
vis1[t.x][t.y]=1;
for(int i=0; i<4; i++)
{
int ax=t.x+dx[i];
int ay=t.y+dy[i];
if(vis1[ax][ay]==1)continue;
if(mapp[ax][ay]=='1')continue;
if(ax<1||ax>H||ay<1||ay>W)continue;
q.push((node)
{
ax,ay
});
dist1[ax][ay]=dist1[t.x][t.y]+1;
}
}
}
void bfs2(int x,int y)
{
dist2[x][y]=0;
q.push((node)
{
x,y
});
while(q.size())
{
node t=q.front();
q.pop();
if(vis2[t.x][t.y])continue;
vis2[t.x][t.y]=1;
for(int i=0; i<4; i++)
{
int ax=t.x+dx[i];
int ay=t.y+dy[i];
if(vis2[ax][ay]==1)continue;
if(mapp[ax][ay]=='1')continue;
if(ax<1||ax>H||ay<1||ay>W)continue;
q.push((node)
{
ax,ay
});
dist2[ax][ay]=dist2[t.x][t.y]+1;
}
}
}
int main()
{
scanf("%d%d",&W,&H);
for(int i=1; i<=H; i++)
{
for(int j=1; j<=W; j++)
{
cin>>mapp[i][j];
if(mapp[i][j]=='2') quex=i,quey=j;
else if(mapp[i][j]=='3') horx=i,hory=j;
else if(mapp[i][j]=='4')
{
++hh;
qq[hh].x=i;
qq[hh].y=j;
}
}
}
memset(dist1,0x3f3f3f3f,sizeof(dist1));
memset(dist2,0x3f3f3f3f,sizeof(dist2));
bfs1(quex,quey);
bfs2(horx,hory);
int ans=0x3f3f3f3f;
for(int i=1; i<=hh; i++)
{
ans=min(ans,dist1[qq[i].x][qq[i].y]+dist2[qq[i].x][qq[i].y]);
}
cout<<ans<<endl;
return 0;
}