void addPolygon( const TIntVector& ib ) { ++polygonCount; TIntVector::const_iterator vit, vitEnd = ib.end(); for( vit = ib.begin(); vit != vitEnd; ++vit ) { int idx = *vit; assert( idx >= 0 && idx < vertexUseCount.size() ); vertices.insert( idx ); ++vertexUseCount[idx]; int idxNext = (vit==vitEnd-1) ? ib.front() : *(vit+1); int idxPrev = (vit==ib.begin()) ? ib.back() : *(vit-1); vertexNexts[idx].push_back( idxNext ); vertexPrevs[idx].push_back( idxPrev ); } }
int main() { #ifndef ONLINE_JUDGE ifstream fIn("input.txt"); cin.rdbuf( fIn.rdbuf() ); #endif int n; int m; cin >> n >> m; TBoolVector dummy(2*n, false); TMatrix g(2*n, dummy); for (int i = 0; i < m; ++i) { int a; int b; cin >> a >> b; --a; --b; g[a][b] = true; g[b][a] = true; } for (int i = 0; i < 2 * n; ++i) { g[i][i] = true; } TIntVector s; s.push_back(0); int next = 1; do { int i = next; for (; i < 2 * n; ++i) { int j = 0; while (j < s.size() && !g[s[j]][i]) { ++j; } if (j == s.size()) { break; } } if (i == 2 * n) { next = s.back() + 1; s.pop_back(); } else { next = 1; s.push_back(i); } } while (!s.empty() && s.size() != n); if (s.size() == n) { for (int i = 0; i < 2 * n; ++i) { if (find(s.begin(), s.end(), i) != s.end()) { cout << i + 1 << " "; } } cout << endl; for (int i = 0; i < 2 * n; ++i) { if (find(s.begin(), s.end(), i) == s.end()) { cout << i + 1 << " "; } } cout << endl; } else { cout << "IMPOSSIBLE\n"; } return 0; }
void Out(const TIntVector& v) { for (TIntVector::const_iterator i = v.begin(); i != v.end(); ++i) printf("%c", 'A' + *i); }
void traceBorder( const TWallVertexVector& vb, TIntVector& polygon, TIntVector& ib ) { static int traceID = 0; ++traceID; int idx0 = getBorderIndex(); assert( idx0 >= 0 && idx0 < vertexTypes.size() ); ib.resize( 0 ); polygon.resize( 0 ); polygon.reserve( vertices.size()/2 ); TIntVector localPolygon; localPolygon.reserve( 128 ); TIntVector localIB; localIB.reserve( 128 ); int idxPrev = idx0; int idx = idx0; int debugCounter = 0; int debugLoopCounter = 0; do { localIB.resize( 0 ); bool willFormLoop; do{ localPolygon.push_back( idx ); borderVertices.erase( idx ); vertexTraceID[idx] = traceID; assert( ++debugCounter <= vertices.size()*2 ); // Next vertex is the neighbor of current, that is not interior // and that is not the previous one. // When there are many possible ones, trace based on angle. int idxNext = -1; SVector2 prevToCurr = vb[idx] - vb[idxPrev]; if( prevToCurr.lengthSq() < 1.0e-6f ) prevToCurr.set( -0.01f, -0.01f ); TIntIntsMap::const_iterator it; it = vertexNexts.find( idx ); assert( it != vertexNexts.end() ); const TIntVector& vnext = it->second; int n = vnext.size(); float bestAngle = 100.0f; for( int i = 0; i < n; ++i ) { int idx1 = vnext[i]; if( idx1 != idxPrev && vertexTypes[idx1] != VTYPE_INTERIOR ) { //if( idx1 != idxPrev ) { SVector2 currToNext = vb[idx1] - vb[idx]; float ang = signedAngle2D( prevToCurr, currToNext ); if( ang < bestAngle ) { bestAngle = ang; idxNext = idx1; } } } assert( bestAngle > -4.0f && bestAngle < 4.0f ); assert( idxNext >= 0 ); willFormLoop = (vertexTraceID[idxNext] == traceID); // Optimization: if best angle is zero, then we're walking // in a straight line. Optimize out the current vertex. if( bestAngle == 0.0f && idx != idx0 && !willFormLoop ) { localPolygon.pop_back(); } idxPrev = idx; idx = idxNext; } while( !willFormLoop ); assert( localPolygon.size() >= 3 ); //if( localPolygon.size() < 3 ) { // return; //} assert( ++debugLoopCounter < vertices.size() ); if( idx == idx0 ) { // The polygon is simple or we found the last loop. // Triangulate local and append to results. triangulator::process( vb, localPolygon, localIB ); polygon.insert( polygon.end(), localPolygon.begin(), localPolygon.end() ); ib.insert( ib.end(), localIB.begin(), localIB.end() ); // We can have separated other loops. Try fetching them as well. idx0 = getBorderIndex(); if( idx0 == -1 ) { return; } else { localPolygon.resize( 0 ); idxPrev = idx0; idx = idx0; } } else { // The polygon must be complex, and we just found a closed loop. // Take only the loop, triangulate it, append to results, continue. TIntVector::const_iterator itLoopStart = std::find( localPolygon.begin(), localPolygon.end(), idx ); assert( itLoopStart != localPolygon.end() ); // append to results TIntVector loopPolygon( itLoopStart, localPolygon.end() ); triangulator::process( vb, loopPolygon, localIB ); polygon.insert( polygon.end(), loopPolygon.begin(), loopPolygon.end() ); ib.insert( ib.end(), localIB.begin(), localIB.end() ); // continue - remove the looped polygon from local localPolygon.resize( itLoopStart - localPolygon.begin() ); } } while( true ); }