어렵지만 얻어갈 것이 많다.
#include <iostream>
#include <vector>
#include <queue>
#include <deque>
#include <tuple>
#include <algorithm>
using namespace std;
int dx[4] = { 1,-1,0,0 };
int dy[4] = { 0,0,1,-1 };
vector<vector<int>> bfs(vector<string>& map, int sx, int sy) {
int x, y;
int n = map.size();
int m = map[0].size();
vector<vector<int>> dist(n, vector<int>(m,-1));
dist[sx][sy] = 0;
queue<pair<int, int>> Q;
Q.push(make_pair(sx, sy));
while (!Q.empty()) {
tie(x, y) = Q.front(); Q.pop();
for (int i = 0; i < 4; i++) {
int xx = x + dx[i];
int yy = y + dy[i];
if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
if (map[xx][yy] == 'x') continue;
if (dist[xx][yy] == -1) {
dist[xx][yy] = dist[x][y] + 1;
Q.push(make_pair(xx, yy));
}
}
}
return dist;
}
int main() {
//freopen("in1.txt", "rt", stdin);
int n, m;
while (1) {
cin >> m >> n;
if (m == 0 && n == 0) {
//cout << -1 << '\n';
break;
}
vector<string> map(n);
vector<pair<int,int>> b(1);
for (int i = 0; i < n; i++) {
cin >> map[i];
for (int j = 0; j < m; j++) {
if (map[i][j] == 'o') b[0] = make_pair(i, j);
else if (map[i][j] == '*') b.push_back(make_pair(i, j));
}
}
int l = b.size();
bool ok = true;
vector<vector<int>> d(l, vector<int>(l));
for (int i = 0; i < l; i++) {
vector<vector<int>> dist = bfs(map, b[i].first, b[i].second);
for (int j = 0; j < l; j++) {
//if (i == j) continue;
d[i][j] = dist[b[j].first][b[j].second];
if (d[i][j] == -1) ok = false;
}
}
if (ok == false) {
cout << -1 << '\n';
continue;
}
vector<int> p(l-1);
for (int i = 0; i < l - 1; i++) {
p[i] = i + 1;
}
int ans = -1;
int cnt = 0;
do {
cnt = d[0][p[0]];
for (int i = 0; i < l - 2; i++) {
cnt += d[p[i]][p[i + 1]];
}
if (ans==-1||cnt < ans) ans = cnt;
} while (next_permutation(p.begin(), p.end()));
cout << ans << '\n';
}
return 0;
}