AcWing 2019. 拖拉机 双端队列+最短路

Posted karshey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AcWing 2019. 拖拉机 双端队列+最短路相关的知识,希望对你有一定的参考价值。

  1. 要求需要移除的干草捆的最小数量,我们把有障碍的地方当作权值是1,没有的地方是0,则此题可以转化为求最短路
  2. 地图中只有0和1的最短路可以用双端队列deque做,其中到的点权值为0就放入队头,为1就放入队尾。则每次取出的队头都是权值最小的情况
  3. 用st表示这个点的最短路是否已经确定。若没确定,当它第一次从队列中取出(front),它的最短路就确定了
  4. 注意边界:(0,0)是终点,而障碍只会出现在[1,1000]范围内,则我们把bfs的范围取到[0,1001]。((0,0)是一定要在范围内的,不然无法遍历,由于多加了一个点,所以我们把范围取到1001相当于再扩大一圈无障碍的范围
  5. 要存最短路的值,有变小才更新和放入队列
  6. 注意,把起点放入队列时不要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. 拖拉机 双端队列+最短路的主要内容,如果未能解决你的问题,请参考以下文章

AcWing 175. 电路维修 BFS+双端队列

浅谈双端队列广搜

Luogu_P2243 电路维修题解 双端队列bfs

codeforces 1064D 双端队列BFS

[lougu2243]

单源最短路的应用与扩展