01bfs 学习笔记

首先 bfs大家应该都会吧()

在求图中边权全部为1的最短路时 可以直接用bfs 复杂度 \(O(n+m)\) 优于 dijkstra \(O(m\log m)\)

那么 对于边权为0/1的边呢

可以考虑用01bfs解决 其实就是把 \(queue\) 换成 \(deque\) 遍历到边权为0的点qush到队头 为1push到队尾

正确性显然 第一次遍历到终点时答案肯定是最小的

P4667 [BalticOI 2011 Day1] Switch the Lamp On

对于每个点 可以走四个方向 显然如果块的方向是对的 加的贡献为0 否则为1

那么把0加到队头 1加到队尾

点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inl inline 
#define gc getchar
#define pc putchar
const int N=5e2+5;
const int M=2e3+5;
const int inf=0x3f3f3f3f;
const int mod=5*7*8*9;
inl int read(){
    int x=0,f=1;char c=gc();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=gc();}
    while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=gc();}
    return x*f;
}
inl void write(int x){
    if(x<0){pc('-');x=-x;}
    if(x>9)write(x/10);
    pc(x%10+'0');
}
inl void writei(int x){write(x);pc(' ');}
inl void writel(int x){write(x);pc('\n');}
int n,m,a[N][N],vis[N][N];
int dx[5]={0,-1,-1,1,1};
int dy[5]={0,-1,1,-1,1};
int tx[5]={0,-1,-1,0,0};
int ty[5]={0,-1,0,-1,0};
int ans[5]={0,0,1,1,0};
deque<pair<int,int> >q;
deque<int>p;
char c;
inl bool check(int x,int y){
    if(x<1||x>n+1||y<1||y>m+1)return 0;
    if(~vis[x][y])return 0;
    return 1;
}
inl void bfs(){
    q.push_back({1,1});p.push_back(0);
    memset(vis,-1,sizeof vis);
    while(!q.empty()){
        int x=q.front().first,y=q.front().second,t=p.front();q.pop_front();p.pop_front();
        if(~vis[x][y])continue;vis[x][y]=t;
        if(x==n+1&&y==m+1)break;
        for(int i=1;i<=4;i++){
            int xx=x+dx[i],yy=y+dy[i];
            if(!check(xx,yy))continue;
            int xp=x+tx[i],yp=y+ty[i];
            if(a[xp][yp]==ans[i]){
                q.push_front({xx,yy});
                p.push_front(vis[x][y]);
            }else{
                q.push_back({xx,yy});
                p.push_back(vis[x][y]+1);
            }
        }
    }
}
signed main(){
    n=read();m=read();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            scanf(" %c",&c);
            a[i][j]=((c=='\\')?0:1);
        }
    }
    bfs();
    if(~vis[n+1][m+1])writel(vis[n+1][m+1]);
    else puts("NO SOLUTION");
    return 0;
}
posted @ 2023-10-18 16:37  xiang_xiang  阅读(35)  评论(0)    收藏  举报