/* 22:21 - 23:37 */ #include #include #define INFTY 10000 typedef struct { int x, y; } point_t; point_t p[16]; char map[22][23]; int adj[16][16]; int w, h, n; int min; int input() { char s[1024]; int i, j; gets(s); sscanf(s, "%d%d", &w, &h); if (w == 0 && h == 0) { return 0; } for (i = 0; i < w+2; i++) { map[0][i] = map[h+1][i] = 'x'; } map[0][w+2] = map[h+1][w+2] = '\0'; for (i = 1; i <= h; i++) { gets(&map[i][1]); map[i][0] = map[i][w+1] = 'x'; map[i][w+2] = '\0'; } w += 2; h += 2; n = 0; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { if (map[i][j] == 'o' || map[i][j] == '*') { n++; } } } return 1; } int flood(int x, int y) { int i, j, k, d, dist[22][22], found, pointdist[16]; static int dx[4] = {0, 1, 0, -1}; static int dy[4] = {1, 0, -1, 0}; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { dist[i][j] = INFTY; } } for (i = 0; i < n; i++) { pointdist[i] = INFTY; } dist[y][x] = 0; pointdist[map[y][x]] = 0; /* Poor Version BFS */ for (d = 0; ; d++) { found = 0; for (i = 1; i < h-1; i++) { for (j = 1; j < w-1; j++) { if (dist[i][j] == d) { for (k = 0; k < 4; k++) { if (map[i+dy[k]][j+dx[k]] != 'x' && dist[i+dy[k]][j+dx[k]] > dist[i][j]) { found = 1; dist[i+dy[k]][j+dx[k]] = d+1; if (0 <= map[i+dy[k]][j+dx[k]] && map[i+dy[k]][j+dx[k]] <= 15) { pointdist[map[i+dy[k]][j+dx[k]]] = d+1; } } } } } } if (!found) { break; } } for (i = 0; i < n; i++) { adj[map[y][x]][i] = adj[i][map[y][x]] = pointdist[i]; } return 0; } int tsp(int visited[16], int cur, int sum) { int i, found = 0; for (i = 0; i < n; i++) { if (!visited[i]) { found = 1; visited[i] = 1; tsp(visited, i, sum + adj[cur][i]); visited[i] = 0; } } if (!found) { if (min > sum) { min = sum; } } } int main() { int i, j, visited[16], k; while (1) { if (!input()) { break; } for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { adj[i][j] = INFTY; } } for (i = k = 0; i < h; i++) { for (j = 0; j < w; j++) { if (map[i][j] == 'o') { map[i][j] = 0; p[0].x = j; p[0].y = i; flood(j, i); } else if (map[i][j] == '*') { k++; map[i][j] = k; p[k].x = j; p[k].y = i; flood(j, i); } } } for (i = 0; i < n; i++) { for (j = 0; j < n; j++) { if (adj[i][j] >= INFTY) { printf("-1\n"); goto quit; } } } min = 100000; for (i = 1; i < n; i++) { visited[i] = 0; } visited[0] = 1; tsp(visited, 0, 0); printf("%d\n", min); quit: continue; } return 0; }