2018 ACM-ICPC北京網路賽 A.Saving Tang Monk II(bfs)
阿新 • • 發佈:2019-01-27
好久沒bfs了,沒想到用三維陣列去標記狀態來進行bfs。。。但仔細一想想,這麼解很有道理。。。
因為這個圖每個格子可以走多遍,我們考慮,對於一個格子,如果帶著相同的氧氣瓶走兩次,那結果是相同的。所以我們從這個約束進行搜尋,開一個三位數字,vis[i][j][k]代表帶著k個氧氣瓶走到第[i][j]個格子。然後就是進行討論。
我們要求到達終點的時間最短,所以可以用優先佇列進行bfs,首先到達終點的肯定是時間最短的。
#include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<queue> using namespace std; int vis[150][150][6]; int dis[4][2]= {{1,0},{-1,0},{0,1},{0,-1}}; char ma[150][150]; int n,m; struct Node { int x; int y; int t; int b; Node(int xx=0,int yy=0,int tt=0,int bb=0):x(xx),y(yy),t(tt),b(bb) {} bool operator <(const Node &a)const { return t>a.t; } };//優先佇列按時間遞增排序。 priority_queue<Node>Q; int xt,yt; int bfs() { Node top; int tx,ty; while(!Q.empty()) { //cout<<"---"<<endl; top=Q.top(); //cout<<top.x<<" "<<top.y<<endl; Q.pop(); for(int i=0; i<4; i++) { tx=top.x+dis[i][0]; ty=top.y+dis[i][1]; if(tx>=1&&tx<=n&&ty>=1&&ty<=m) {//cout<<"+++"<<tx<<" "<<ty<<" "<<top.b<<" "<<vis[tx][ty][top.b-1]<<endl; if(ma[tx][ty]=='#') { if(top.b<1)continue;//沒有氧氣瓶不能進入毒氣室 } if(ma[tx][ty]=='#'&&top.b>=1&&!vis[tx][ty][top.b-1])//可以進入 { vis[tx][ty][top.b-1]=1;//標記狀態 不用重複搜尋 Q.push(Node(tx,ty,top.t+2,top.b-1));//時間增加2,用掉一個氧氣瓶 } if(ma[tx][ty]=='.'&&!vis[tx][ty][top.b]) { vis[tx][ty][top.b]=1; Q.push(Node(tx,ty,top.t+1,top.b)); } if(ma[tx][ty]=='P'&&top.t>=0&&!vis[tx][ty][top.b]) { vis[tx][ty][top.b]=1; Q.push(Node(tx,ty,top.t,top.b));//因為是P,所以不需要時間 } if(ma[tx][ty]=='B'&&top.b<5&&!vis[tx][ty][top.b+1])//最多隻能帶5個,需要判斷 { vis[tx][ty][top.b+1]=1; Q.push(Node(tx,ty,top.t+1,top.b+1)); } if(ma[tx][ty]=='S'&&!vis[tx][ty][top.b])//注意S可以重複走 { vis[tx][ty][top.b]=1; Q.push(Node(tx,ty,top.t+1,top.b)); } if(ma[tx][ty]=='T') { return top.t+1; } } } } return -1; } int main() { while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0)break; memset(vis,0,sizeof(vis)); while(!Q.empty())Q.pop(); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { cin>>ma[i][j]; if(ma[i][j]=='S') { Q.push(Node(i,j,0,0)); vis[i][j][0]=1; } if(ma[i][j]=='T') { xt=i; yt=j; } } } int ans=bfs(); printf("%d\n",ans); } }