1140 Cleaning Robot
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1140&lang=jp
ほうしん
幅優先探索で、各汚れたタイルと初期位置との距離を全て求めておきTSPにして解く。
ソース
#include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<algorithm> using namespace std; #define REP(i,a,b) for(i=a; i<b; ++i) #define rep(i,n) REP(i,0,n) char mp[20][20]; int dist[20][20]; bool seen[20][20]; int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; const int inf = 1<<29; int tsp(int start,vector< vector<int> > G) { const int n = G.size(), N = 1<<n; int i,j,ret = inf; vector< vector<int> > X(n, vector<int>(N, inf)); vector< vector<int> > Y(n, vector<int>(N, -1)); rep(i,n) { X[i][1<<i] = G[start][i]; Y[i][1<<i] = start; } for(int S = 1; S < N; ++S) { rep(i,n) { if(!(S & (1<<i))) continue; rep(j,n) { if(S & (1<<j)) continue; if(X[j][S|(1<<j)] > X[i][S]+G[i][j]) { X[j][S|(1<<j)] = X[i][S]+G[i][j]; Y[j][S|(1<<j)] = i; } } } } if(X[start].back() >= inf) return -1; rep(i,n) ret = min(X[i].back(), mm); return mm; } int main() { int w,h,i,j,k,l,objnum; string s; while(cin>>w>>h, w|h) { objnum = 1; rep(i,h) { cin>>s; rep(j,w) { mp[i][j] = s[j]; if(s[j] == 'o') mp[i][j] = 0; if(s[j] == '*') mp[i][j] = objnum++; } } vector<vector<int> > G(objnum, vector<int>(objnum, inf)); rep(i,objnum) G[i][i] = 0; rep(i,objnum) { int sx,sy; rep(j,h) rep(k,w) if(mp[j][k] == i) sx = k, sy = j; memset(dist, -1, sizeof(dist)); memset(seen, false, sizeof(seen)); queue<pair<int,int> > Q; Q.push(make_pair(sy,sx)); seen[sy][sx] = true; dist[sy][sx] = 0; while(!Q.empty()) { int x = Q.front().second,y = Q.front().first; Q.pop(); rep(l,4) { int nx = x+dx[l],ny = y+dy[l]; if(nx < 0 || nx >= w || ny < 0 || ny >= h || seen[ny][nx]) continue; if(mp[ny][nx] == 'x') continue; if(dist[ny][nx] == -1) dist[ny][nx] = dist[y][x]+1; else dist[ny][nx] = min(dist[ny][nx],dist[y][x]+1); seen[ny][nx] = true; Q.push(make_pair(ny,nx)); } } rep(j,h) rep(k,w) { if(0 <= mp[j][k] && mp[j][k] <= objnum) { if(dist[j][k] == -1) continue; G[mp[j][k]][i] = G[i][mp[j][k]] = dist[j][k]; } } } long long ans = tsp(0,G); if(ans >= inf) cout<<-1<<endl; else cout<<ans<<endl; } }