/*! @file b.cc @brief Solves "Pile Up!" ( http://www.acm-japan.org/past-icpc/domestic2002/B.htm ) @author Yuta Kitamura @date 2005-04-26 */ // start 14:07 // end 15:32 #include #include #include #include using std::cout; using std::cin; using std::endl; using std::list; using std::find; using std::distance; typedef unsigned int uint; typedef list Pile; typedef list Field; template bool sizeCompare(const T& lhs, const T& rhs) { if (lhs.size() == rhs.size()) lhs < rhs; else return lhs.size() < rhs.size(); } int main() { while (cin) { uint nCubes; cin >> nCubes; if (nCubes == 0) break; Field f; for (uint i = 0; i < nCubes; ++i) f.push_back(Pile(1, i + 1)); while (true) { // debug //for (Field::iterator itF = f.begin(); itF != f.end(); ++itF) { //cout << "["; //for (Pile::iterator itP = itF->begin(); itP != itF->end(); ++itP) { // if (itP != itF->begin()) cout << ", "; // cout << *itP; //} //cout << "]"; //} //cout << endl; uint i, j; cin >> i >> j; if (i == 0 && j == 0) break; if (j == 0) { Field::iterator itF; Pile::iterator itP; for (Field::iterator it = f.begin(); it != f.end(); ++it) { itF = it; itP = find(it->begin(), it->end(), i); if (itP != it->end()) break; } Pile& p = *itF; for (Pile::iterator it = itP; it != p.end(); ++it) f.push_back(Pile(1, *it)); p.erase(itP, p.end()); if (p.empty()) f.erase(itF); } else if (i != j) { Field::iterator itF1, itF2; Pile::iterator itP1, itP2; for (Field::iterator it = f.begin(); it != f.end(); ++it) { Pile::iterator itP = find(it->begin(), it->end(), i); if (itP != it->end()) { itP1 = itP; itF1 = it; } itP = find(it->begin(), it->end(), j); if (itP != it->end()) { itP2 = itP; itF2 = it; } } Pile& p1 = *itF1; Pile& p2 = *itF2; if (&p1 == &p2) { if (distance(p1.begin(), itP1) < distance(p1.begin(), itP2)) { for (Pile::iterator it = itP1; it != p1.end(); ++it) if (it != itP1 && it != itP2) f.push_back(Pile(1, *it)); Pile newPile; newPile.push_back(*itP2); newPile.push_back(*itP1); f.push_back(newPile); p1.erase(itP1, p1.end()); if (p1.empty()) f.erase(itF1); } } else { p2.push_back(*itP1); Pile::iterator it = itP1; ++it; for (; it != p1.end(); ++it) f.push_back(Pile(1, *it)); p1.erase(itP1, p1.end()); if (p1.empty()) f.erase(itF1); } } } f.sort(sizeCompare); for (Field::iterator it = f.begin(); it != f.end(); ++it) cout << it->size() << endl; cout << "end" << endl; } return 0; }