您的位置:首页 > 其它

Codeforces 591E - Three States 【BFS】

2017-11-22 00:45 344 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  591E - Three States