Cod sursa(job #1234386)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 27 septembrie 2014 12:07:31
Problema Paduri de multimi disjuncte Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
#include <bits/stdc++.h>

using namespace std;

const int Nmax = 100000 + 2;

int Left[Nmax], Right[Nmax], Parent[Nmax];

bool isRoot( int p )
{
    return ( !Parent[p] || ( Left[ Parent[p] ] != p && Right[ Parent[p] ] != p ) );
}

void rotateRight( int p )
{
    int q = Parent[p];
    int r = Parent[q];

    if ( ( Left[q] = Right[p] ) != 0 )
        Parent[ Left[q] ] = q;

    Right[p] = q;
    Parent[q] = p;

    if ( ( Parent[p] = r ) != 0 )
    {
        if ( Left[r] == q )
            Left[r] = p;
        else
            Right[r] = p;
    }
}

void rotateLeft( int p )
{
    int q = Parent[p];
    int r = Parent[q];

    if ( ( Right[q] = Left[p] ) != 0 )
        Parent[ Right[q] ] = q;

    Left[p] = q;
    Parent[q] = p;

    if ( ( Parent[p] = r ) != 0 )
    {
        if ( Left[r] = q )
            Left[r] = p;
        else
            Right[r] = p;
    }
}

void splay( int p )
{
    while ( !isRoot( p ) )
    {
        int q = Parent[p];

        if ( isRoot( q ) )
        {
            if ( Left[q] == p )
                rotateRight( p );
            else
                rotateLeft( p );
        }
        else
        {
            int r = Parent[q];

            if ( Left[r] == q )
            {
                if ( Left[q] == p )
                {
                    rotateRight( p );
                    rotateRight( p );
                }
                else
                {
                    rotateLeft( p );
                    rotateRight( p );
                }
            }
            else
            {
                if ( Left[q] == p )
                {
                    rotateRight( p );
                    rotateLeft( p );
                }
                else
                {
                    rotateLeft( p );
                    rotateLeft( p );
                }
            }
        }
    }
}

int expose( int p )
{
    int last = 0;

    for ( int x = p; x != 0; x = Parent[x] )
    {
        splay( x );
        Left[x] = last;
        last = x;
    }

    splay( p );
    return last;
}

int findRoot( int p )
{
    expose( p );

    while ( Right[p] != 0 ) p = Right[p];

    splay( p );

    return p;
}

void link( int x, int y )
{
    expose( x );
    Parent[x] = y;
}

void afis()
{
    for ( int i = 1; i <= 5; ++i )
    {
        cout << i << ": " << Left[i] << " " << Right[i] << " " << Parent[i] << endl;
    }
}

int N, M;

int main()
{
    ifstream in("disjoint.in");
    ofstream out("disjoint.out");

    in >> N >> M;

    for ( int i = 1, tip, x, y; i <= M; ++i )
    {
        in >> tip >> x >> y;

        if ( tip == 1 )
            link( x, y );
        else
        {
            if ( findRoot( x ) == findRoot( y ) )
                out << "DA\n";
            else
                out << "NU\n";
        }
    }

    return 0;
}