Codeforces 591E - Three States 【BFS】


E. Three States


time limit per test  5seconds

memory limit per test      512megabytes


The famous global economic crisis is approaching rapidly, so thestates of Berman, Berance and Bertaly formed an alliance and allowed theresidents of all member states to freely pass through the territory of any ofthem. In addition, it was decided that a road between the states should bebuilt to guarantee so that one could any point of any country can be reachedfrom any point of any other State.

Since roads are always expensive, the governments of the statesof the newly formed alliance asked you to help them assess the costs. To dothis, you have been issued a map that can be represented as a rectangle tableconsisting of n rows and m columns. Any cell of the map either belongs to one of threestates, or is an area where it is allowed to build a road, or is an area wherethe construction of the road is not allowed. A cell is called passable, if it belongs to one ofthe states, or the road was built in this cell. From any passable cells you canmove up, down, right and left, if the cell that corresponds to the movementexists and is passable.

Your task is to construct a road inside a minimum number ofcells, so that it would be possible to get from any cell of any state to anycell of any other state using only passable cells.

It is guaranteed that initially it is possible to reach any cellof any state from any cell of this state, moving only along its cells. It isalso guaranteed that for any state there is at least one cell that belongs toit.

Input

The first line of the input contains the dimensions of the map n and m (1 ≤ n, m ≤ 1000) —the number of rows and columns respectively.

Each of the next n lines contain m characters, describing the rows of themap. Digits from 1 to 3 represent the accessory to the corresponding state. Thecharacter '.'corresponds to the cell where it is allowed to build a road and the character '#' means no construction is allowed inthis cell.

Output

Print a single integer — the minimum number of cells you need to build a roadinside in order to connect all the cells of all states. If such a goal isunachievable, print -1.

Examples

Input

4 5
11..2
#..22
#.323
.#333

Output

2

Input

1 5
1#2#3

Output

-1

 


【题意】


给出一个n*m的地图,地图上有数字1,2,3代表三个国家的城市,'.'代表可以造路的地方,'#'代表不可以造路的地方。已知每个国家的城市构成一个联通块,现在问最少范围较小,我们考虑去枚举三个国家的交汇点,然后更新最小花费。


【思路】


我们用dis[i][x][y]表示第i个城市到达点(x,y)的最小距离。


对于dis的求解,我们只要进行一次bfs即可。


那么我们对于当前枚举的点(x,y)来说,最小花费即为dis[1][x][y]+dis[2][x][y]+dis[3][x][y],值得注意的是,若(x,y)处为'.',答案需要减去2,因为算的时候这个点造了三次路。


#include <cstdio>
#include <cmath>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
#define mst(a,b) memset((a),(b),sizeof(a))
#define rush() int T;scanf("%d",&T);while(T--)

typedef long long ll;
const int maxn = 1005;
const ll mod = 1e9+7;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
const int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};


int n,m;
char mp[maxn][maxn];
int vis[maxn][maxn];
int dis[5][maxn][maxn];
int tag[5];

struct node
{
    int x,y,step;
    bool friend operator <(node a,node b)
    {
        return a.step>b.step;
    }
}now,nex;

bool inbound(node a)
{
    return a.x>=0&&a.x<n&&a.y>=0&&a.y<m;
}

void bfs(int x,int y,int sta)
{
    mst(vis,0);
    priority_queue<node>q;
    for(int i=0;i<n;i++)
    for(int j=0;j<m;j++)
    {
        dis[sta][i][j]=INF;
        if(mp[i][j]-'0'==sta)
        {
            now.x=i;
            now.y=j;
            now.step=0;
            q.push(now);
            dis[sta][i][j]=0;
        }
    }
    while(q.size())
    {
        now=q.top();
        vis[now.x][now.y]=0;
        q.pop();
        for(int i=0;i<4;i++)
        {
            nex.x=now.x+dir[i][0];
            nex.y=now.y+dir[i][1];
            nex.step=now.step;
            if(inbound(nex)&&mp[nex.x][nex.y]!='#')
            {
                if(mp[nex.x][nex.y]=='.') nex.step++;
                if(dis[sta][nex.x][nex.y]>nex.step)
                {
                    dis[sta][nex.x][nex.y]=nex.step;
                    if(vis[nex.x][nex.y]==0)
                    {
                        q.push(nex);
                    }
                }
            }
        }
    }
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        mst(tag,0);
        for(int i=0;i<n;i++)
        {
            scanf("%s",mp[i]);
        }
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(mp[i][j]>='1'&&mp[i][j]<='3'&&tag[mp[i][j]-'0']==0)
            {
                bfs(i,j,mp[i][j]-'0');
                tag[mp[i][j]-'0']=1;
            }
        }
        int ans=INF;
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(mp[i][j]!='#')
            {
                int flag=0;
                int cnt=0;
                for(int k=1;k<=3;k++)
                {
                    if(dis[k][i][j]==INF) flag=1;
                    cnt+=dis[k][i][j];
                }
                if(flag==1) continue;
                if(mp[i][j]=='.') cnt-=2;
                ans=min(ans,cnt);
            }
        }
        if(ans==INF) puts("-1");
        else printf("%d\n",ans);
    }
    return 0;
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值