题解:
以3个大陆为起点,都dfs一遍,求出该大陆到其他点的最小距离是多少, 然后枚举每个点作为3个大陆的路径交点。
代码:
#includeusing namespace std;#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);#define LL long long#define ULL unsigned LL#define fi first#define se second#define pb push_back#define ep emplace_back#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define lch(x) tr[x].son[0]#define rch(x) tr[x].son[1]#define max3(a,b,c) max(a,max(b,c))#define min3(a,b,c) min(a,min(b,c))typedef pair pll;const int inf = 0x3f3f3f3f;const int _inf = 0xc0c0c0c0;const LL INF = 0x3f3f3f3f3f3f3f3f;const LL _INF = 0xc0c0c0c0c0c0c0c0;const LL mod = (int)1e9+7;const int N = 1e3 + 100;int n, m;LL dis[N][N][3];char s[N][N];int dx[] = { 1, -1, 0, 0};int dy[] = { 0, 0, -1, 1};deque q;void bfs(int k){ for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) dis[i][j][k] = inf; char kk = k + '0' + 1; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= m; ++j){ if(s[i][j] == kk){ dis[i][j][k] = 0; q.push_back(pll(i,j)); } } } while(!q.empty()){ pll t = q.front(); q.pop_front(); for(int _ = 0; _ < 4; ++_){ int nx = t.fi + dx[_]; int ny = t.se + dy[_]; if(nx < 1 || nx > n || ny < 1 || ny > m || s[nx][ny] == '#') continue; int dd = dis[t.fi][t.se][k] + (s[nx][ny] == '.'); if(dd < dis[nx][ny][k]){ dis[nx][ny][k] = dd; if(s[nx][ny] == '.') q.push_back(pll(nx,ny)); else q.push_front(pll(nx, ny)); } } }}int main(){ scanf("%d%d", &n, &m); for(int i = 1; i <= n; ++i) scanf("%s", s[i]+1); for(int i = 0; i < 3; ++i) bfs(i); LL ans = inf; for(int i = 1; i <= n; ++i){ for(int j = 1; j <= m; ++j){ int f = 0; if(s[i][j] == '.') f = 2; ans = min(ans, dis[i][j][0] + dis[i][j][1] + dis[i][j][2] - f); } } if(ans == inf) ans = -1; cout << ans << endl; return 0;}