吐槽下题目:不愧是cf,真的就是阅读理解,抛开复杂的题意,就是一个广搜,不过需要存三种情况.......
题意:现在有三个地盘,然后要修一条可以连通三个城市的道路,并且要最短,可以穿过其他人的地盘来连通
题解:记忆广搜,以每个点来广搜会超时,但是以每个地盘的数字来进行广搜就可以了
先把一个地盘的所有点压入队列,然后来广搜全局,再用数组记录当前到其他剩余点所需要的时间戳,
然后重复两次
最后遍历全图对于每个点来进行三个时间戳求和,取最小,即答案
时间复杂度:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y;
}r,f;
queue<node>Q;
int n,m,T[4][1005][1005],dx[]={0,0,1,-1},dy[]={1,-1,0,0};
char R[1005][1005];
void BFS(int a)
{
int i,j,X,Y;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
T[a][i][j]=1e8;
if(R[i][j]-'0'==a)T[a][i][j]=0,r.x=i,r.y=j,Q.push(r);
}
while(!Q.empty())
{
f=Q.front(),Q.pop();
for(i=0;i<4;i++)
{
X=f.x+dx[i],Y=f.y+dy[i],j=T[a][f.x][f.y];
if(X<0||X>=n||Y<0||Y>=m||R[X][Y]=='#')continue;
if(R[X][Y]=='.')j++;
if(j<T[a][X][Y])T[a][X][Y]=j,r.x=X,r.y=Y,Q.push(r);
}
}
}
int main()
{
int i,j,t,ans=1e8;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)scanf("%s",R[i]);
BFS(1),BFS(2),BFS(3);
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
if(R[i][j]=='#')continue;
t=T[1][i][j]+T[2][i][j]+T[3][i][j];
if(R[i][j]=='.')t-=2;
ans=min(ans,t);
}
if(ans==1e8)ans=-1;
printf("%d\n",ans);
}
京公网安备 11010502036488号