ZOJ 1649 BFS/最短路
阿新 • • 發佈:2018-12-21
給你起點和終點,然後讓你在二維迷宮裡面去找一個人,和一般的BFS的唯一差別就是這裡面設定了一些守衛,你要殺掉這個守衛就必須要多花費一秒的時間,讓你求出最終到達的最短的步數。 對於一般的BFS我們知道,它不但可以去找路徑,而且還能保證它最終的結果是最短路。因為它記錄了步數,它知道每一步最大能拓展的位置。那麼在這道題裡面,我們直接去求卻是不行的,我們最先找到的那一條路徑卻未必是最短的,那麼我們就要按照步數的順序來拓展這個BFS,我們可以考慮用優先佇列給步數排序,這樣保證步數少的在前面,這樣最後找到就是答案。 當然我們也可以把這個問題轉化成最短路,對於沒有守衛的普通格子,相當於邊權為1,對於有守衛的格子邊權為2,然後我們直接跑spfa就可以了,不過一段時間不寫居然也搞出了一堆傻逼操作,比如什麼起始位置的距離沒有置為0,胡亂鬆弛。總而言之還是基礎不紮實。 另外還有一個優先佇列(其實不單單是優先佇列)過載運算子都是去過載小於號,它們實際上都是用小於來確定順序的。 SPFA:
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; char mp[200+15][200+15]; int vis[200+15][200+15]; int stx,sty,edx,edy; int dx[4]={0,0,-1,1}; int dy[4]={1,-1,0,0}; int dis[200+15][200+15]; int n,m; struct node{ int x,y; node(){} node(int x,int y):x(x),y(y) {} }; void spfa() { queue<node> q; vis[stx][sty]=1; dis[stx][sty]=0; q.push(node(stx,sty)); while(!q.empty()) { node u=q.front();q.pop(); int x=u.x,y=u.y; vis[x][y]=0; for(int i=0;i<4;i++) { int nx=x+dx[i],ny=y+dy[i]; if(nx<1||nx>n||ny<1||ny>m||mp[nx][ny]=='#') continue; if(mp[nx][ny]=='.'||mp[nx][ny]=='r') { if(dis[nx][ny]>dis[x][y]+1) { dis[nx][ny]=dis[x][y]+1; if(!vis[nx][ny]) { q.push(node(nx,ny)); vis[nx][ny]=1; } } } if(mp[nx][ny]=='x') { if(dis[nx][ny]>dis[x][y]+2) { dis[nx][ny]=dis[x][y]+2; if(!vis[nx][ny]) { q.push(node(nx,ny)); vis[nx][ny]=1; } } } } } } int main() { ios::sync_with_stdio(false); cin.tie(0); while(cin>>n>>m) { memset(dis,inf,sizeof(dis)); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>mp[i][j]; if(mp[i][j]=='a') stx=i,sty=j; if(mp[i][j]=='r') edx=i,edy=j; } spfa(); if(dis[edx][edy]!=inf) printf("%d\n",dis[edx][edy]); else printf("Poor ANGEL has to stay in the prison all his life.\n"); } return 0; }
優先佇列BFS
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int inf=0x3f3f3f3f; const int maxn=200+15; char mp[maxn][maxn]; bool vis[maxn][maxn]; int n,m,stx,sty,edx,edy; int dx[4]={0,0,-1,1}; int dy[4]={1,-1,0,0}; struct node { int x,y,step; node() {} node(int x,int y,int step):x(x),y(y),step(step){} }; bool operator<(const node& a,const node& b){ if(a.step>b.step) return true; else return false; } int bfs() { priority_queue<node> q; vis[stx][sty]=true; q.push(node(stx,sty,0)); while(!q.empty()) { node u=q.top();q.pop(); int x=u.x,y=u.y,step=u.step; if(x==edx&&y==edy) return step; for(int i=0;i<4;i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(nx<1||nx>n||ny<1||ny>m||vis[nx][ny]||mp[nx][ny]=='#') continue; if(mp[nx][ny]=='.'||mp[nx][ny]=='r') { vis[nx][ny]=true; q.push(node(nx,ny,step+1)); } if(mp[nx][ny]=='x') { vis[nx][ny]=true; q.push(node(nx,ny,step+2)); } } } return -1; } void clear() { memset(vis,0,sizeof(vis)); } int main() { ios::sync_with_stdio(false); cin.tie(0); while(cin>>n>>m) { clear(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { cin>>mp[i][j]; if(mp[i][j]=='a') stx=i,sty=j; if(mp[i][j]=='r') edx=i,edy=j; } int ans=bfs(); if(ans!=-1) cout<<ans<<endl; else cout<<"Poor ANGEL has to stay in the prison all his life."<<endl; } return 0; }