Jailbreak 個人訓練賽
阿新 • • 發佈:2018-12-02
https://vj.e949.cn/5e9d1ef965fc5f2bb34f0d3ff5e7eca4?v=1542378645 j題
題意:兩個人逃出監獄的最小開門數,門開啟後不會關閉。
思路:對圖加邊,預設空地,然後最優為兩人最後會和一起出去。以(0,0)和兩個人的起點搜三遍存圖。遍歷所有點假設這是集結點求最小開門數。
搜圖的時用優先佇列維護最小開門的點,普通佇列維護的是步數最小。
#include <bits/stdc++.h> #include<stdio.h> #define inf 0x3f3f3f3f using namespace std; struct code { int x,y,di; } tt,tep; bool operator <(code a,code b) { return a.di>b.di; } int dap[105][105],n,m; char s; int dist1[105][105],dist2[105][105],dist3[105][105]; int nx[4][2]= {1,0,0,1,-1,0,0,-1}; bool ok(int x,int y) { if(x>=0&&x<=n+1&&y>=0&&y<=m+1) return true; else return false; } void dfs1(int x,int y) { int visit[105][105]; memset(visit,0,sizeof(visit)); priority_queue<code>p; tt.x=x; tt.y=y; p.push(tt); dist1[x][y]=0; visit[x][y]=1; while(!p.empty()) { tt=p.top(); p.pop(); for(int i=0; i<4; i++) { int tx=tt.x+nx[i][0],ty=tt.y+nx[i][1]; if(!ok(tx,ty)||visit[tx][ty]==1) continue; if(dap[tx][ty]==1||dap[tx][ty]==0) { tep.x=tx; tep.y=ty; if(dap[tx][ty]==1) dist1[tx][ty]=dist1[tt.x][tt.y]+1; else dist1[tx][ty]=dist1[tt.x][tt.y]; tep.di=dist1[tx][ty]; visit[tx][ty]=1; p.push(tep); } } } } void dfs2(int x,int y) { int visit[105][105]; memset(visit,0,sizeof(visit)); priority_queue<code>p; tt.x=x; tt.y=y; p.push(tt); dist2[x][y]=0; visit[x][y]=1; while(!p.empty()) { tt=p.top(); p.pop(); for(int i=0; i<4; i++) { int tx=tt.x+nx[i][0],ty=tt.y+nx[i][1]; if(!ok(tx,ty)||visit[tx][ty]==1) continue; if(dap[tx][ty]==1||dap[tx][ty]==0) { tep.x=tx; tep.y=ty; if(dap[tx][ty]==1) dist2[tx][ty]=dist2[tt.x][tt.y]+1; else dist2[tx][ty]=dist2[tt.x][tt.y]; tep.di=dist2[tx][ty]; visit[tx][ty]=1; p.push(tep); } } } } void dfs3(int x,int y) { int visit[105][105]; memset(visit,0,sizeof(visit)); priority_queue<code>p; tt.x=x; tt.y=y; p.push(tt); dist3[x][y]=0; visit[x][y]=1; while(!p.empty()) { tt=p.top(); p.pop(); for(int i=0; i<4; i++) { int tx=tt.x+nx[i][0],ty=tt.y+nx[i][1]; if(!ok(tx,ty)||visit[tx][ty]==1) continue; if(dap[tx][ty]==1||dap[tx][ty]==0) { tep.x=tx; tep.y=ty; if(dap[tx][ty]==1) dist3[tx][ty]=dist3[tt.x][tt.y]+1; else dist3[tx][ty]=dist3[tt.x][tt.y]; tep.di=dist3[tx][ty]; visit[tx][ty]=1; p.push(tep); } } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); memset(dap,0,sizeof(dap)); int x=-1,y=-1,tx=-1,ty=-1; for(int i=1; i<=n; i++) { getchar(); for(int j=1; j<=m; j++) { scanf("%c",&s); if(s=='*') dap[i][j]=2; else if(s=='#') dap[i][j]=1; else dap[i][j]=0; if(s=='$') { if(x==-1) { x=i; y=j; } else { tx=i; ty=j; } } } } dfs1(0,0); dfs2(x,y); dfs3(tx,ty); int ans=inf; for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) if(dap[i][j]==1) ans=min(ans,dist1[i][j]+dist2[i][j]+dist3[i][j]-2); else if(dap[i][j]==0) ans=min(ans,dist1[i][j]+dist2[i][j]+dist3[i][j]); } ans=min(ans,dist1[0][0]+dist2[0][0]+dist3[0][0]); printf("%d\n",ans); } return 0; }