AcWing 2019. 拖拉机 双端队列+最短路
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 2019. 拖拉机 双端队列+最短路相关的知识,希望对你有一定的参考价值。
- 要求需要移除的干草捆的最小数量,我们把有障碍的地方当作权值是1,没有的地方是0,则此题可以转化为求最短路。
- 地图中只有0和1的最短路可以用双端队列deque做,其中到的点权值为0就放入队头,为1就放入队尾。则每次取出的队头都是权值最小的情况。
- 用st表示这个点的最短路是否已经确定。若没确定,当它第一次从队列中取出(front),它的最短路就确定了
- 注意边界:(0,0)是终点,而障碍只会出现在[1,1000]范围内,则我们把bfs的范围取到[0,1001]。((0,0)是一定要在范围内的,不然无法遍历,由于多加了一个点,所以我们把范围取到1001相当于再扩大一圈无障碍的范围)
- 要存最短路的值,有变小才更新和放入队列。
- 注意,把起点放入队列时不要st[x][y]=1,否则会遍历不到这个起点,答案就是初始化时的最大值。
/*
把有障碍当作该点权值为1,则此题可以转化为最短路问题
用双端队列进行bfs
要存下到某个点的最小权值
*/
#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);
// st[x][y]=1;
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;//取到它说明它是0,或者是第一个1,反正是当前最小的
// cout<<t.x<<" "<<t.y<<endl;
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)//界是1000
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;//有障碍,则权值为1
ans=INT_MAX;
//cout<<nn<<" "<<mm;
bfs();
cout<<ans;
return 0;
以上是关于AcWing 2019. 拖拉机 双端队列+最短路的主要内容,如果未能解决你的问题,请参考以下文章