[Gym-100625J] 搜尋
阿新 • • 發佈:2018-12-22
具體思路:首先,具體思路是兩個人一起走到一個點,然後兩個人按照同樣的道路走出去,聽了別人的思路,還有一種特殊情況需要考慮,就是中間一堵牆,兩個人都直接在邊界上,這個時候可以新加一個點,然後兩個人到這個點的開門數都是0,然後三個搜尋,新加的點到圖裡面所有能走的點的最小路徑,兩個人分別到達圖內的點和新加的點的最小開門數,然後列舉每一個點,找最小就可以了。
AC程式碼:
#include<iostream> #include<stack> #include<iomanip> #include<queue> #include<iomanip> #include<cmath> #include<stdio.h> #include<map> #include<string> #include<cstring> #include<set> #include<vector> using namespace std; # define inf 100000 # define ll long long # define maxn 100+100 int dis[maxn][maxn];// 計算從外面的點到裡面每個點的最小開門數 int num1[maxn][maxn];// 計算第一個人到達某一個點的最小開門數 int num2[maxn][maxn];//計算第二個人到達某一個點的最小開門數 int vis[maxn][maxn];//dfs的過程中標記 char Map[maxn][maxn]; int n,m,k; int f[2][4]= {{1,-1,0,0},{0,0,1,-1}}; bool judge(int t1,int t2) { if(t1>=0&&t2>=0&&t1<=n+1&&t2<=m+1)return true; return false; } struct node { int x,y,num; node(int xx,int yy,int zz) { x=xx; y=yy; num=zz; } friend bool operator < (node t1,node t2) { return t2.num<t1.num;//把想要的放在後面,符號方向不變 } }; void bfs1(int x,int y) { priority_queue<node>q; q.push(node(x,y,0)); vis[x][y]=1; dis[x][y]=0; while(!q.empty()) { node temp=q.top(); q.pop(); for(int i=0; i<4; i++) { int t1=temp.x+f[0][i]; int t2=temp.y+f[1][i]; if(judge(t1,t2)&&vis[t1][t2]==0&&Map[t1][t2]!='*') { vis[t1][t2]=1; if(Map[t1][t2]=='#') { q.push(node(t1,t2,temp.num+1)); dis[t1][t2]=dis[temp.x][temp.y]+1; } else { q.push(node(t1,t2,temp.num)); dis[t1][t2]=dis[temp.x][temp.y]; } } } } } void bfs2(int x,int y) { priority_queue<node>q; q.push(node(x,y,0)); vis[x][y]=1; num1[x][y]=0; while(!q.empty()) { node temp=q.top(); q.pop(); for(int i=0; i<4; i++) { int t1=temp.x+f[0][i]; int t2=temp.y+f[1][i]; if(judge(t1,t2)&&vis[t1][t2]==0&&Map[t1][t2]!='*') { vis[t1][t2]=1; if(Map[t1][t2]=='#') { q.push(node(t1,t2,temp.num+1)); num1[t1][t2]=num1[temp.x][temp.y]+1; } else { q.push(node(t1,t2,temp.num)); num1[t1][t2]=num1[temp.x][temp.y]; } } } } } void bfs3(int x,int y) { priority_queue<node>q; q.push(node(x,y,0)); vis[x][y]=1; num2[x][y]=0; while(!q.empty()) { node temp=q.top(); q.pop(); for(int i=0; i<4; i++) { int t1=temp.x+f[0][i]; int t2=temp.y+f[1][i]; if(judge(t1,t2)&&vis[t1][t2]==0&&Map[t1][t2]!='*') { vis[t1][t2]=1; if(Map[t1][t2]=='#') { q.push(node(t1,t2,temp.num+1)); num2[t1][t2]=num2[temp.x][temp.y]+1; } else { q.push(node(t1,t2,temp.num)); num2[t1][t2]=num2[temp.x][temp.y]; } } } } } int main() { int T; scanf("%d",&T); int x1,y1,x2,y2; while(T--) { int flag=1; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%s",Map[i]+1); } for(int i=0; i<=m+1; i++) { Map[0][i]='.'; Map[n+1][i]='.'; } for(int i=0; i<=n+1; i++) { Map[i][0]='.'; Map[i][m+1]='.'; } for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(Map[i][j]!='$')continue; if(flag==1) { x1=i; y1=j; flag=0; } else if(flag==0) { x2=i; y2=j; break; } } } for(int i=0; i<=n+1; i++) for(int j=0; j<m+1; j++) { dis[i][j]=inf; num1[i][j]=inf; num2[i][j]=inf; } memset(vis,0,sizeof(vis)); bfs1(0,0); memset(vis,0,sizeof(vis)); bfs2(x1,y1); memset(vis,0,sizeof(vis)); bfs3(x2,y2); int minn=inf; minn=min(minn,dis[0][0]+num1[0][0]+num2[0][0]); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(Map[i][j]=='#') minn=min(minn,dis[i][j]+num1[i][j]+num2[i][j]-2); else minn=min(minn,dis[i][j]+num1[i][j]+num2[i][j]); } } printf("%d\n",minn); } return 0; } /* 5 9 ****#**** *..#.#..* ****.**** *$#.#.#$* ********* 5 11 *#********* *$*...*...* *$*.*.*.*.* *...*...*.* *********.* 9 9 *#**#**#* *#**#**#* *#**#**#* *#**.**#* *#*#.#*#* *$##*##$* *.#.#.#.* ********* */