CF1228D Complete Tripartite

Topic Link

problem analysis

3 requires the points into groups, within each group there is no edge, each point and each not has its edge between the set point.

So, after even the direction of the edge points within each group are the same, and \ (U \) not adjacent the point \ (U \) of the same group.

Considering that only \ (3 \) group, so the direct \ (O (n + m) \) violent enough.May be required by the code to understand what

Reference program

#include <bits/stdc++.h>
using namespace std;
 
const int Maxn = 100010;
const int Maxm = 300010;
struct edge {
    int x, y;
    edge() {}
    edge( int _x, int _y ) : x( _x ), y( _y ) {}
    inline bool operator < ( const edge Other ) const {
        return x < Other.x || x == Other.x && y < Other.y;
    }
    inline bool operator == ( const edge Other ) const {
        return x == Other.x && y == Other.y;
    }
    inline bool operator > ( const edge Other ) const {
        return x > Other.x || x == Other.x && y > Other.y;
    }
};
int n, m;
edge Edge[ Maxm << 1 ];
int Color[ Maxn ], App[ Maxn ], Cnt;
 
int main() {
    scanf( "%d%d", &n, &m );
    for( int i = 1; i <= m; ++i ) scanf( "%d%d", &Edge[ i ].x, &Edge[ i ].y );
    for( int i = 1; i <= m; ++i ) Edge[ i + m ] = edge( Edge[ i ].y, Edge[ i ].x );
    m <<= 1;
    sort( Edge + 1, Edge + m + 1 );
    for( int i = 1; i <= n; ++i ) {
        if( Color[ i ] ) continue;
        ++Cnt;
        if( Cnt > 3 ) {
            printf( "-1\n" );
            return 0;
        }
 
        memset( App, 0, sizeof( App ) );
        int l = upper_bound( Edge + 1, Edge + m + 1, edge( i, 0 ) ) - Edge;
        int r = l - 1;
        while( Edge[ r + 1 ].x == i ) {
            ++r;
            App[ Edge[ r ].y ] = 1;
        }
//      printf( "l = %d, r = %d\n", l, r );
//      printf( "A %d\n", i );
//      printf( "App : " ); for( int j = 1; j <= n; ++j ) printf( "%d ", App[ j ] ); printf( "\n" );
//      for( int j = l; j <= r; ++j ) printf( "%d %d\n", Edge[ j ].x, Edge[ j ].y );
 
        for( int j = 1; j <= n; ++j ) {
            if( App[ j ] == 0 && Color[ j ] != 0 ) {
                printf( "-1\n" );
                return 0;
            }
            if( App[ j ] ) continue;
            Color[ j ] = Cnt;
            int L = upper_bound( Edge + 1, Edge + m + 1, edge( j, 0 ) ) - Edge;
            for( int k = l; k <= r; ++k ) {
                int R = L + ( k - l );
//              printf( "k = %d, R = %d, r = %d\n", k, R, l + ( k - l ) );
                if( Edge[ R ].x != j || Edge[ R ].y != Edge[ l + ( k - l ) ].y ) {
                    printf( "-1\n" );
                    return 0;
                }
            }
        }
//      printf( "A %d\n", i );
//      for( int j = 1; j <= n; ++j ) printf( "%d ", Color[ j ] ); printf( "\n" );
    }
    if( Cnt != 3 ) {
        printf( "-1\n" );
        return 0;
    }
    for( int i = 1; i <= n; ++i ) printf( "%d ", Color[ i ] ); printf( "\n" );
    return 0;
}

Guess you like

Origin www.cnblogs.com/chy-2003/p/11617489.html