Exemple #1
0
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	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 );
	}