题
- 要求需要移除的干草捆的最小数量,我们把有障碍的地方当作权值是1,没有的地方是0,则此题可以转化为求最短路。
- 地图中只有0和1的最短路可以用双端队列deque做,其中到的点权值为0就放入队头,为1就放入队尾。则每次取出的队头都是权值最小的情况。
- 用st表示这个点的最短路是否已经确定。若没确定,当它第一次从队列中取出(front),它的最短路就确定了
- 注意边界:(0,0)是终点,而障碍只会出现在[1,1000]范围内,则我们把bfs的范围取到[0,1001]。((0,0)是一定要在范围内的,不然无法遍历,由于多加了一个点,所以我们把范围取到1001相当于再扩大一圈无障碍的范围)
- 要存最短路的值,有变小才更新和放入队列。
- 注意,把起点放入队列时不要st[x][y]=1,否则会遍历不到这个起点,答案就是初始化时的最大值。
#include<bits/stdc++.h>
using namespace std;
#define fir(i,a,n) for(int i=a;i<=n;i++)
#define mem(a,x) memset(a,x,sizeof(a));
typedef long long ll;
const int N=1e3+10;
int g[N][N];
int n,x,y;
int ans;
struct node
{
int x,y;
};
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int d[N][N];
int st[N][N];
void bfs()
{
mem(d,0x3f);
deque<node>q;
q.push_back({x,y});
d[x][y]=0;
while(q.size())
{
node t=q.front();
q.pop_front();
if(st[t.x][t.y]) continue;
st[t.x][t.y]=1;
if(t.x==0&&t.y==0) break;
for(int i=0;i<4;i++)
{
int xx=t.x+dx[i];
int yy=t.y+dy[i];
if(xx>=0&&xx<=1001&&yy>=0&&yy<=1001)
{
int w=g[xx][yy];
if(d[xx][yy]>d[t.x][t.y]+w)
{
d[xx][yy]=d[t.x][t.y]+w;
if(w) q.push_back({xx,yy});
else q.push_front({xx,yy});
}
}
}
}
ans=min(ans,d[0][0]);
}
int main()
{
cin>>n>>x>>y;
while(n--)
{
int a,b;cin>>a>>b;
g[a][b]=1;
}
ans=INT_MAX;
bfs();
cout<<ans;
return 0;
}