注意求最小值的方法。
const int maxn = 108 ;
int lx[maxn] , ly[maxn] ;
int Left[maxn] ;
int w[maxn][maxn] ;
bool S[maxn] , T[maxn] ;
int n ;
bool match(int i){
S[i] = 1 ;
for(int j = 1 ; j <= n ; j++){
if(!T[j] && lx[i] + ly[j] == w[i][j]){
T[j] = 1 ;
if(!Left[j] || match(Left[j])){
Left[j] = i ;
return 1 ;
}
}
}
return 0 ;
}
void update(){
int a = 1<<30 ;
for(int i = 1 ; i <= n ; i++){
if(S[i]){
for(int j = 1 ; j <= n ; j++){
if(! T[j]) a = min(a , lx[i]+ly[j]-w[i][j]) ;
}
}
}
for(int i = 1 ; i <= n ; i++){
if(S[i]) lx[i] -= a ;
if(T[i]) ly[i] += a ;
}
}
int km(){
for(int i = 1 ; i <= n ; i++){
Left[i] = lx[i] = ly[i] = 0 ;
for(int j = 1 ; j <= n ; j++)
lx[i] = max(lx[i] , w[i][j]) ;
}
for(int i = 1 ; i <= n ; i++){
while(1){
for(int j = 1 ; j <= n ; j++)
S[j] = T[j] = 0 ;
if(match(i)) break ;
else update() ;
}
}
int s = 0 ;
for(int i = 1 ; i <= n ; i++) s += w[Left[i]][i] ;
return s ;
}
char g[48][48] ;
int N , M ;
int can(int x , int y){
return 1 <= x && x <= N && 1 <= y && y <= M ;
}
int d[4][2] = {{-1,0},{0,-1},{1,0},{0,1}} ;
int dist[48][48] ;
bool in[48][48] ;
vector<pair<int , int> > lisx , lisb ;
void bfs(int sx , int sy , int id){
queue< pair<int ,int> > q ;
q.push(make_pair(sx,sy)) ;
memset(dist , 63 , sizeof(dist)) ;
dist[sx][sy] = 0 ;
in[sx][sy] = 1 ;
while(! q.empty()){
pair<int , int> now = q.front() ;
q.pop() ;
in[now.first][now.second] = 0 ;
for(int i = 0 ; i < 4 ; i++){
int x = now.first + d[i][0] ;
int y = now.second + d[i][1] ;
if(! can(x , y) || g[x][y] == '#') continue ;
if(dist[x][y] > dist[now.first][now.second] + 1){
dist[x][y] = dist[now.first][now.second] + 1 ;
if(!in[x][y]){
in[x][y] = 1 ;
q.push(make_pair(x , y)) ;
}
}
}
}
for(int i = 0 ; i < lisb.size() ; i++){
w[id][i+1] = min(w[id][i+1] , dist[lisb[i].first][lisb[i].second]) ;
}
}
int main(){
int t , i , j , b , x ;
cin>>t ;
while(t--){
cin>>N>>M ;
for(i = 1 ; i <= N ; i++) scanf("%s" , g[i]+1) ;
lisx.clear() ;
lisb.clear() ;
for(i = 1 ; i <= N ; i++){
for(j = 1 ; j <= M ; j++){
if(g[i][j] == 'B')
lisb.push_back(make_pair(i , j)) ;
else if(g[i][j] == 'X')
lisx.push_back(make_pair(i , j)) ;
}
}
n = lisb.size() ;
memset(w , 63 , sizeof(w)) ;
for(i = 0 ; i < lisx.size() ; i++){
bfs(lisx[i].first , lisx[i].second , i+1) ;
}
for(i = 1 ; i <= n ; i++)
for(j = 1 ; j <= n ; j++){
w[i][j] = -w[i][j] ;
}
cout<< -km() << endl ;
}
return 0 ;
}