P4667 Switch the Lamp On (双端队列bfs

#include "bits/stdc++.h"
using namespace std;
using PII = pair;
int t;
int n,m;
int dis[510][510];
char g[510][510];
int vis[510][510];
int dx[]={1,1,-1,-1};
int dy[]={1,-1,1,-1};
int ix[]={1,1,0,0};
int iy[]={1,0,1,0};
char cs[]="\\//\\";
void sol(){
    deque dq;
    memset(dis,0x3f,sizeof dis);
    dis[0][0] = 0;
    dq.push_back({0,0});
    while(dq.size()){
        auto p = dq.front();
        dq.pop_front();
        int x = p.first;
        int y = p.second;
        if(vis[x][y])continue;
        vis[x][y] = true;
        for(int i=0;i<4;i++){
            int xx = x + dx[i];
            int yy = y + dy[i];
            if(xx >=0 && xx <= n && yy >= 0 && yy <= m){
                int gx = x + ix[i];
                int gy = y + iy[i];
                int w = 0;
                if(g[gx][gy] != cs[i]) w = 1;
                if(dis[xx][yy] > dis[x][y] + w){
                    dis[xx][yy] = dis[x][y] + w;
                    if(w) dq.push_back({xx,yy});
                    else dq.push_front({xx,yy});

                }
            }
        }
    }
    if(dis[n][m] == 0x3f3f3f3f){
        cout<<"NO SOLUTION";
    }else{
        cout<>n>>m;
    for(int i=1;i<=n;i++)scanf("%s",g[i]+1);
    sol();
    puts("");

}

虽然是说双端队列bfs,但本质上跟应该是个dij

但这题边权只有01俩种,所有可以用双端队列维护,如果dis没有变化,就加在对头,有变化,就放在队尾

将这个题抽象为一个图,有电路直接连接的就点边权为0,需要转向的边权就为1,

于是其实就可以是一个单源最短路。用类似dij思想,

——————————————————————————————

这题方向转移还不太一样,还有判定数组确实有点东西的说

你可能感兴趣的:(搜索,宽度优先,算法,图论)