B17 双端队列BFS Switch the Lamp On
视频链接:B17 双端队列BFS Switch the Lamp On_哔哩哔哩_bilibili
Luogu P4667 [BalticOI 2011 Day1]Switch the Lamp On




#include <cstring> #include <iostream> #include <algorithm> #include <deque> using namespace std; typedef pair<int,int> PII; const int N=510; int n,m; char e[N][N]; //格内斜边 int d[N][N]; //操作步数 bool vis[N][N]; //判重 char es[]="\\/\\/"; //斜边 左上角开始顺时针记录 int dx[]={-1,-1,1,1},dy[]={-1,1,1,-1}; //格点增量 int ex[]={-1,-1,0,0},ey[]={-1,0,0,-1}; //格子增量 deque<PII> q; //双端队列 int bfs(){ memset(d,0x3f,sizeof d); d[0][0]=0; q.push_back({0,0}); while(q.size()){ PII u=q.front(); q.pop_front(); int x=u.first,y=u.second; //父格点 if(vis[x][y]) continue; //出队优化 vis[x][y]=1; for(int i=0; i<4; i++){ int a=x+dx[i],b=y+dy[i]; //子格点 if(a<0||a>n||b<0||b>m) continue; int ea=x+ex[i],eb=y+ey[i]; //格子 int dd=d[x][y]+(e[ea][eb]!=es[i]); if(dd<d[a][b]){ //入队优化 d[a][b]=dd; if(e[ea][eb]!=es[i])q.push_back({a,b}); else q.push_front({a,b}); } } } return d[n][m]; } int main(){ scanf("%d%d",&n,&m); for(int i=0; i<n; i++) scanf("%s",e[i]); int dd=bfs(); if(dd==0x3f3f3f3f) puts("NO SOLUTION"); else printf("%d\n",dd); }
浙公网安备 33010602011771号