题目链接:https://ac.nowcoder.com/acm/problem/111125
题目大意:有一个地图有1,2,3个阵营。现在要修建路让1,2,3可以连接起来。如果地图是'1','2','3'这个单元格不用花费。'#':不可以修建, '.':费用为1.现在问最小费用是多少?
思路:我们知道一定是在地图上一个格子上汇合。枚举这个格子。dis1+dis2+dis3。如果这个格子是'.'有两个阵营在这个单元多修建了需要-2。
dis:用01bfs就可以了。
#include<bits/stdc++.h> using namespace std; char s[1005][1005]; int vis[3][1005][1005], f[3][1005][1005]; int xx[4]={0, 1, -1, 0}; int yy[4]={1, 0, 0, -1}; int n, m; struct node{ int x, y, T; }; deque<node> q; void bfs(int pos){ for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ if(s[i][j]=='1'+pos){ q.push_back(node{i, j, 0}); } } } while(!q.empty()){ node t=q.front(); q.pop_front(); f[pos][t.x][t.y]=t.T; for(int k=0; k<4; k++){ int x=t.x+xx[k], y=t.y+yy[k]; if(x<=n&&x>=1&&y<=m&&y>=1&&!vis[pos][x][y]&&s[x][y]!='#'){ vis[pos][x][y]=1; if(s[x][y]=='.'){ q.push_back(node{x, y, t.T+1}); } else{ q.push_front(node{x, y, t.T}); } } } } } int main(){ scanf("%d%d", &n , &m); for(int i=1; i<=n; i++){ scanf("%s", s[i]+1); } bfs(0); bfs(1); bfs(2); int ans=1<<30; for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ if(s[i][j]=='#'||!vis[0][i][j]||!vis[1][i][j]||!vis[2][i][j]) continue; if(s[i][j]=='.'){ ans=min(ans, f[0][i][j]+f[1][i][j]+f[2][i][j]-2); } else{ ans=min(ans, f[0][i][j]+f[1][i][j]+f[2][i][j]); } } } if(ans==1<<30){ printf("-1\n"); } else{ printf("%d\n", ans); } return 0; }