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;
}