E. Three States - Codeforces Round #327 (Div. 2) 590C States(广搜)
题目大意:有一个M*N的矩阵,在这个矩阵里面有三个王国,编号分别是123,想知道这三个王国连接起来最少需要再修多少路。
分析:首先求出来每个王国到所有能够到达点至少需要修建多少路,然后枚举所有点求出来最少的即可。
代码如下:
---------------------------------------------------------------------------------------------------------
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<queue> using namespace std; const int MAXN = 1007; const int oo = 1e9+7; int dir[4][2] = { {1,0},{0,1},{-1,0},{0,-1} }; char G[MAXN][MAXN]; struct node { int step[3]; }a[MAXN][MAXN]; struct point { int x, y; }; void BFS(int M, int N, int k) {///第k个王国到达所有点的最短距离 queue<point> Q; point q, s; for(int i=0; i<M; i++) for(int j=0; j<N; j++) { if(G[i][j] == k+'1') { q.x = i, q.y = j; a[i][j].step[k] = 0; Q.push(q); } } while(Q.size()) { q = Q.front();Q.pop(); for(int i=0; i<4; i++) { s = q; s.x += dir[i][0]; s.y += dir[i][1]; if(s.x>=0&&s.x<M && s.y>=0&&s.y<N && G[s.x][s.y] != '#') { int t = (G[s.x][s.y]=='.' ? 1:0); if(a[s.x][s.y].step[k]==-1 || a[q.x][q.y].step[k]+t < a[s.x][s.y].step[k]) {///因为王国之间没有不用修路,所有可能会回搜 a[s.x][s.y].step[k] = a[q.x][q.y].step[k] + t; Q.push(s); } } } } } int main() { int M, N; scanf("%d%d", &M, &N); for(int i=0; i<M; i++) scanf("%s", G[i]); memset(a, -1, sizeof(a)); for(int i=0; i<3; i++) BFS(M, N, i); int ans = oo; for(int i=0; i<M; i++) for(int j=0; j<N; j++) { if(a[i][j].step[0]!=-1 && a[i][j].step[1]!=-1 && a[i][j].step[2]!=-1) {///如果这个点三个王国都能够到达 int t = (G[i][j]=='.' ? 1:0); ans = min(ans, a[i][j].step[0]+a[i][j].step[1]+a[i][j].step[2]-t*2); } } if(ans == oo) ans = -1; printf("%d\n", ans); return 0; }