特殊的bfs——01BFS
0-1BFS用来解决:边权值为0或1,或者能够转化为这种边权值的最短路问题,时间复杂度O( v点+e边 )。
主要操作:用deque,从0边扩展到的点push到队首,反之则到队尾。
模板题:SPOJ - KATHTHI
题意:起点走到终点,n×m的网格,每个位置有一个小写字母,若s[x][y]=s[nx][ny],则移动的花费为0,否则花费为1,求花费最少
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 2e3+100; const int INF = 0x3f3f3f3f; const int mod = 998244353; const int dx[]={0,1,0,-1}; const int dy[]={1,0,-1,0}; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} struct node { int x,y; }; node s,t; int n,m,k,T; char G[maxn][maxn]; struct _01bfs { deque<node> q; int dis[maxn][maxn]; int x,y,xx,yy; bool vis[maxn][maxn]; node now; bool flag; void init() { memset(dis,0x3f,sizeof(dis)); //memset(vis,0,sizeof(vis)); q.clear(); } int bfs() { q.push_front(s); dis[s.x][s.y]=0; while (!q.empty()) { now=q.front(); q.pop_front(); //if (vis[now.x][now.y]) continue; 一般情况下,可以不用 //vis[now.x][now.y]=1; for (int i=0;i<4;i++) { x=now.x,y=now.y; xx=x+dx[i],yy=y+dy[i]; if (xx<0||xx>=n||yy<0||yy>=m) continue; flag=1; if (G[x][y]==G[xx][yy]) flag=0; if (dis[x][y]+flag<dis[xx][yy]) // 如果是<=就要用vis { dis[xx][yy]=dis[x][y]+flag; if (!flag) q.push_front({xx,yy}); else q.push_back({xx,yy}); } } } return dis[t.x][t.y]; } }hehehe; int main() { T=read(); while (T--) { n=read(),m=read(); for (int i=0;i<n;i++) scanf("%s",G[i]); s.x=0,s.y=0,t.x=n-1,t.y=m-1; hehehe.init(); cout<<hehehe.bfs()<<endl; } return 0; }
相似题:UVA11573 Ocean Currents
题意类似
#include <bits/stdc++.h> #define debug freopen("r.txt","r",stdin) #define mp make_pair #define ri register int using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 2e3+100; const int INF = 0x3f3f3f3f; const int mod = 998244353; const int dx[8]={-1,-1,0,1,1,1,0,-1}; const int dy[8]={0,1,1,1,0,-1,-1,-1}; inline ll read(){ll s=0,w=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w;} ll qpow(ll p,ll q){return (q&1?p:1)*(q?qpow(p*p%mod,q/2):1)%mod;} struct node { int x,y; }; node s,t; int n,m,k; char G[maxn][maxn]; struct _01bfs { deque<node> q; int dis[maxn][maxn]; int x,y,xx,yy; bool vis[maxn][maxn]; node now; bool flag; void init() { memset(dis,0x3f,sizeof(dis)); //memset(vis,0,sizeof(vis)); q.clear(); } int bfs() { q.push_front(s); dis[s.x][s.y]=0; while (!q.empty()) { now=q.front(); q.pop_front(); if (now.x==t.x && now.y==t.y) break; //if (vis[now.x][now.y]) continue; 一般情况下,可以不用 //vis[now.x][now.y]=1; for (int i=0;i<8;i++) { x=now.x,y=now.y; xx=x+dx[i],yy=y+dy[i]; if (xx<1||xx>n||yy<1||yy>m) continue; flag=0; if (G[x][y]-'0'==i) flag=1; if (dis[x][y]+!flag<dis[xx][yy]) // 如果是<=就要用vis { dis[xx][yy]=dis[x][y]+!flag; if (flag) q.push_front({xx,yy}); else q.push_back({xx,yy}); } } } return dis[t.x][t.y]; } }hehehe; int main() { n=read(),m=read(); for (int i=1;i<=n;i++) scanf("%s",G[i]+1); k=read(); for (int i=1;i<=k;i++) { s.x=read(),s.y=read(),t.x=read(),t.y=read(); hehehe.init(); cout<<hehehe.bfs()<<endl; } return 0; }