POJ 1137 - The New Villa
http://poj.org/problem?id=1137
概要
r 個の部屋をもつ別荘がある.1番目の部屋が玄関で,r 番目の部屋が寝室.各部屋には明かりがある. d 個の廊下があり,それぞれ1つの部屋と1つの部屋を繋いでいる. s 個のスイッチがあり,各スイッチはいずれかの部屋に存在し,いずれかの部屋の明かりを点けたり消したりできる.
今,玄関のみ明かりが点いており,自分も玄関にいる. スイッチを押したり,廊下を渡って明かりの点いている部屋に移動したりしながら,最終的に寝室に行き,寝室のみ明かりが点いている状態にしたい. 最小のステップ数でそのような状態するとき,どのように行動すればいいかを答える.
ただし,1ステップは
- 1つスイッチを押す
- 1つ廊下を渡って別の部屋へ行く
のいずれかに対応する.
制約
- 1 <= r <= 10
解法
状態数は r * 2^r 程度なので,これで単に BFS すればいい.
しかし,同じ最小のステップ数にする行動の仕方は一通りとは限らないのに,どれを出力すればよいか示されていないし Special Judge でもない糞ゲー.
- スイッチの操作より部屋の移動を優先する
- 部屋の移動は,入力で先に与えられたほうを優先する
- スイッチの操作は,スイッチに対応する明かりのある部屋番号が小さいほうを優先する
みたいにしたら通った.
poj/1137.cc1 #include <iostream> 2 #include <sstream> 3 #include <vector> 4 #include <queue> 5 #include <algorithm> 6 using namespace std; 7 8 int main() 9 { 10 int R, D, S; 11 for (int Ti = 1; cin >> R >> D >> S && R != 0; Ti++) { 12 vector<vector<int> > g(R); 13 for (int i = 0; i < D; i++) { 14 int u, v; 15 cin >> u >> v; 16 --u; --v; 17 g[u].push_back(v); 18 g[v].push_back(u); 19 } 20 vector<vector<int> > switches(R); 21 for (int i = 0; i < S; i++) { 22 int u, v; 23 cin >> u >> v; 24 --u; --v; 25 if (u != v) { 26 switches[u].push_back(v); 27 } 28 } 29 for (int i = 0; i < R; i++) { 30 sort(switches[i].begin(), switches[i].end()); 31 } 32 33 queue<pair<int,int> > q; 34 q.push(make_pair(0, 1)); 35 vector<vector<int> > dist(R, vector<int>(1<<R, 1000000)); 36 vector<vector<pair<bool,int> > > prev(R, vector<pair<bool,int> >(1<<R)); 37 dist[0][1] = 0; 38 cout << "Villa #" << Ti << endl; 39 while (!q.empty()) { 40 int n = q.front().first; 41 int s = q.front().second; 42 q.pop(); 43 const int d = dist[n][s]; 44 if (n == R-1 && s == (1<<(R-1))) { 45 cout << "The problem can be solved in " << d << " steps:" << endl; 46 vector<string> msg; 47 for (int i = 0; i < d; i++) { 48 ostringstream oss; 49 const int j = prev[n][s].second; 50 if (prev[n][s].first) { 51 // switch 52 oss << "- Switch " << (s & (1<<j) ? "on" : "off") << " light in room " << j+1 << "."; 53 s ^= (1<<j); 54 } else { 55 // move 56 oss << "- Move to room " << n+1 << "."; 57 n = j; 58 } 59 msg.push_back(oss.str()); 60 } 61 for (vector<string>::reverse_iterator it = msg.rbegin(); it != msg.rend(); ++it) { 62 cout << *it << endl; 63 } 64 goto NEXT; 65 } 66 // goto next room 67 for (vector<int>::const_iterator it(g[n].begin()); it != g[n].end(); ++it) { 68 if (s & (1<<*it) && d+1 < dist[*it][s]) { 69 dist[*it][s] = d+1; 70 prev[*it][s].first = false; 71 prev[*it][s].second = n; 72 q.push(make_pair(*it, s)); 73 } 74 } 75 // turn switch 76 for (vector<int>::const_iterator it(switches[n].begin()); it != switches[n].end(); ++it) { 77 const int t = s ^ (1<<*it); 78 if (d+1 < dist[n][t]) { 79 dist[n][t] = d+1; 80 prev[n][t].first = true; 81 prev[n][t].second = *it; 82 q.push(make_pair(n, t)); 83 } 84 } 85 } 86 cout << "The problem cannot be solved." << endl; 87 NEXT: 88 cout << endl; 89 } 90 return 0; 91 }