0-index 宏孩儿。
大概是求距离错了?希望大家点评一下。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define MP make_pair
#define fi first
#define se second
template<typename T> void chkmin(T &a, const T &b){
if(a > b) a = b;
}
template<typename T> void chkmax(T &a, const T &b){
if(a < b) a = b;
}
const int R = 50, N = 15;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};
int r, c, n;
char grid[R][R];
int idx[R][R], tot;
int g[N][N], d[R][R];
void bfs(int sx, int sy){
queue<pii> q;
q.push(MP(sx, sy));
while(!q.empty()){
pii p = q.front(); q.pop();
for(int i = 0; i < 4; i++){
int nx = p.fi + dx[i];
int ny = p.se + dy[i];
if(nx < 0 || nx >= r || ny < 0 || ny >= c) continue;
if(~idx[nx][ny]) continue;
if(grid[nx][ny] == 'S' || grid[nx][ny] == '.') continue;
idx[nx][ny] = idx[sx][sy];
q.push(MP(nx, ny));
}
}
}
void pathfind(int sx, int sy){
memset(d, 0x3f, sizeof(d));
queue<pii> q;
q.push(MP(sx, sy));
d[sx][sy] = 0;
while(!q.empty()){
pii p = q.front(); q.pop();
for(int i = 0; i < 4; i++){
int nx = p.fi + dx[i];
int ny = p.se + dy[i];
if(nx < 0 || nx >= r || ny < 0 || ny >= c || d[nx][ny] < 1E9) continue;
d[nx][ny] = d[p.fi][p.se] + 1;
q.push(MP(nx, ny));
}
}
/*for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
cerr << d[i][j] << " \n"[j == c - 1];
}
}*/
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
if(grid[i][j] == 'X'){
chkmin(g[idx[sx][sy]][idx[i][j]], d[i][j] - 1);
}
}
}
}
int dp[1 << N][N];
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
memset(dp, 0x3f, sizeof(dp));
memset(g, 0x3f, sizeof(g));
memset(idx, -1, sizeof(idx));
cin >> r >> c;
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
cin >> grid[i][j];
}
}
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
if(grid[i][j] == 'X' && !~idx[i][j]){
idx[i][j] = tot++;
bfs(i, j);
}
}
}
/*for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
cerr << idx[i][j] << " \n"[j == c - 1];
}
}*/
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
if(grid[i][j] == 'X'){
pathfind(i, j);
}
}
}
// cerr << "tot: " << tot << '\n';
/*for(int i = 0; i < tot; i++){
for(int j = 0; j < tot; j++){
cerr << g[i][j] << " \n"[j == tot - 1];
}
}*/
for(int i = 0; i < tot; i++) g[i][i] = 0;
for(int i = 0; i < tot; i++){
dp[1 << i][i] = 0;
}
for(int S = 0; S < (1 << tot); S++){
for(int u = 0; u < tot; u++){
if(dp[S][u] >= 1E9) continue;
if(!(S >> u & 1)) continue;
for(int v = 0; v < tot; v++){
if(S >> v & 1) continue;
chkmin(dp[S | 1 << v][v], dp[S][u] + g[u][v]);
}
}
}
int ans = 1E9;
for(int i = 0; i < tot; i++){
chkmin(ans, dp[(1 << tot) - 1][i]);
}
cout << ans << '\n';
return 0;
}