[CF590C] Three States - BFS
Description
给你一个?×?的地图,’.’为荒地,’#’为石头,数字为国家,求最少将多少个荒地修为路可以将三个国家联通。无解输出‘-1’。
Solution
四个点的树,四种可能
需要计算出每个点到每个连通块的最近距离,以及连通块之间相互的最近距离
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1005;
#define MAP_EMPTY '.'
#define MAP_WALL '#'
#define MAP_BLOCK(x) ('0' + x)
char a[N][N];
int n, m;
int d[4][N][N], cod[4][4];
const int adi[4] = {0, 0, -1, 1};
const int adj[4] = {1, -1, 0, 0};
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i] + 1;
memset(d, 0x1f, sizeof d);
memset(cod, 0x1f, sizeof cod);
for (int t = 1; t <= 3; t++)
{
queue<pair<int, int>> que;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (a[i][j] == MAP_BLOCK(t))
que.push({i, j}), d[t][i][j] = 0;
while (que.size())
{
auto [i, j] = que.front();
que.pop();
for (int dir = 0; dir < 4; dir++)
{
int di = adi[dir];
int dj = adj[dir];
int ni = di + i;
int nj = dj + j;
if (ni > 0 && nj > 0 && ni <= n && nj <= m && d[t][i][j] + 1 < d[t][ni][nj] && a[ni][nj] != MAP_WALL)
{
d[t][ni][nj] = d[t][i][j] + 1;
que.push({ni, nj});
}
}
}
}
for (int x = 1; x <= 3; x++)
{
for (int y = 1; y <= 3; y++)
{
if (x != y)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (a[i][j] == MAP_BLOCK(y))
cod[x][y] = min(cod[x][y], d[x][i][j]);
}
}
}
}
}
int ans = 1e18;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
ans = min(ans, d[1][i][j] + d[2][i][j] + d[3][i][j] - 2);
}
}
ans = min(ans, cod[1][2] + cod[2][3] - 2);
ans = min(ans, cod[2][1] + cod[1][3] - 2);
ans = min(ans, cod[1][3] + cod[3][2] - 2);
if (ans < 1e12)
cout << ans << endl;
else
cout << -1;
}