Luogu Topic Link: Cows Grooming
Topic description
Input and output format
Input format:
Output format:
Input and output example
Input example #1:
6 16
................
..XXXX....XXX...
...XXXX....XX...
.XXXX......XXX..
........XXXXX...
..XXX....XXX....
Sample output #1:
4
Briefly describe the meaning of the question: Given a matrix with three points (??) on the matrix, it is required to change at least a few points to make these three points become one point.
Obviously we can find the distance between every two points , the answer is the sum of the distances from the other two points to this point.
However, this is problematic, such as this:
...X.....X...
.............
......X......
In this way, these points do not need to be connected to a point, so on the basis of the previous answer, it is good to enumerate the sum of the distances of the three points to the same position and update the answer.
Steps:
- Wide search to find the point to which each location belongs.
- Deep search finds the shortest length from a point to each position.
- Take the minimum value for the case of connecting to the same point and three points and then outside.
- The final answer is -2 (because when calculating the distance, the length connected to a point is calculated, so the grid connected to it is not counted).
#include<bits/stdc++.h>
using namespace std;
const int N=500+5;
const int inf=2147483647;
int n, m, cnt = 0, ans = inf;
char a[N][N];
int col[N][N];
int mn[N][N];
int d[4][N][N];
int mv[]={1,0,-1,0,1};
struct node{
int x, y;
};
bool ok(node nt){
if(nt.x < 1 || nt.x > n) return false;
if(nt.y < 1 || nt.y > m) return false;
if(col[nt.x][nt.y] || a[nt.x][nt.y] != 'X') return false;
return true;
}
void bfs(int x,int y){
cnt++; queue <node> q;
q.push((node){x,y}); col[x][y] = cnt;
node now, nt;
while(!q.empty()){
now = q.front(); q.pop();
for(int i=0;i<4;i++){
nt.x = now.x+mv[i]; nt.y = now.y+mv[i+1];
if(ok(nt)) col[nt.x][nt.y] = cnt, q.push(nt);
}
}
}
void dfs(int color,int x,int y,int step){
if(d[color][x][y] <= step) return;
d[color][x][y] = step;
int nx, ny;
for(int i=0;i<4;i++){
nx = x+mv[i], ny = y+mv[i+1];
if(nx>=1 && nx<=n && ny>=1 && ny<=m)
dfs(color,nx,ny,step+1);
}
}
int main(){
//freopen("war.in","r",stdin);
//freopen("war.out","w",stdout);
char ch; cin >> n >> m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
cin >> a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!col[i][j] && a[i][j] == 'X') bfs(i,j);
memset(d,127/3,sizeof(d));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(a[i][j] == 'X') dfs(col[i][j],i,j,0);
memset(mn,127/3,sizeof(mn));
for(int c=1;c<=3;c++)
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
mn[col[i][j]][c] = mn[c][col[i][j]] = min(mn[c][col[i][j]],d[c][i][j]);
ans = min(mn[1][2]+mn[2][3],min(mn[1][3]+mn[3][2],mn[3][1]+mn[1][2]));
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]);
printf("%d\n",ans-2);
return 0;
}