有三个国家要建立联盟,每个数字表示一个联盟一共3个,‘.’表示可以修路,‘#’表示不可以修路,问最少要多少要建立多少条路才可以是任意一个联盟的城市到任意其他国家的城市。
解法:
计算每个点到1,2,3的距离,特判等于0的情况,用inf的时候不能太大。
#include "iostream"
#include "cstdio"
#include "string.h"
#include "queue"
#include "math.h"
using namespace std;
const int inf=10000000;
int go[2][4]={{0,-1,0,1},{-1,0,1,0}};
int to[3][1010][1010],n,m;
char map[1010][1010];
typedef pair<int,int>pii;
bool judge(int x,int y)
{
if(x<0||y<0||x>=n||y>=m||map[x][y]=='#')
return false;
return true;
}
void cal(int dist[1010][1010],char type)
{
queue<pii>que;
pii now,temp;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(map[i][j]==type)
{
que.push(make_pair(i,j));
dist[i][j]=0;
}
else
dist[i][j]=inf;
}
}
while(!que.empty())
{
temp=que.front();
que.pop();
for(int i=0;i<4;i++)
{
now.first=temp.first+go[0][i];
now.second=temp.second+go[1][i];
if(!judge(now.first,now.second))
continue;
if(map[now.first][now.second]=='.')
{
if(dist[now.first][now.second]>dist[temp.first][temp.second]+1)
{
dist[now.first][now.second]=dist[temp.first][temp.second]+1;
que.push(now);
}
}
else
{
if(dist[now.first][now.second]>dist[temp.first][temp.second])
{
dist[now.first][now.second]=dist[temp.first][temp.second];
que.push(now);
}
}
}
}
}
int main(int argc,char* argv[])
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
scanf(" %s",map[i]);
for(int i=0;i<3;i++)
cal(to[i],(char)'1'+i);
int b=inf,c=inf;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(map[i][j]=='2')
b=min(b,to[0][i][j]);
else if(map[i][j]=='3')
c=min(c,to[0][i][j]);
}
}
if(b==0&&c==0)
printf("0\n");
else
{
int ans=inf;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(map[i][j]=='.')
ans=min(ans,(to[0][i][j]+to[1][i][j]+to[2][i][j]-2));
if(ans>=n*m)
puts("-1");
else
printf("%d\n",ans);
}
return 0;
}