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;
}

浙公网安备 33010602011771号