Cod sursa(job #1234515)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 27 septembrie 2014 15:08:26
Problema Paduri de multimi disjuncte Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 3.47 kb
#include <bits/stdc++.h>

using namespace std;

class LinkCutTree
{
public:

    struct Node
    {
        int id;
        Node *parent, *left, *right;

        explicit Node( const int ID ) : id(ID), parent(NULL), left(NULL), right(NULL) {}

        bool isRoot()
        {
            return ( !parent || ( parent->left != this && parent->right != this ) );
        }
    };

    void rotateRight( Node* &p )
    {
        Node *q = p->parent;
        Node *r = q->parent;

        if ( ( q->left = p->right ) != NULL )
            q->left->parent = q;

        p->right = q;
        q->parent = p;

        if ( ( p->parent = r ) != NULL )
        {
            if ( r->left == q )
                r->left = p;
            else
                r->right = p;
        }
    }

    void rotateLeft( Node* &p )
    {
        Node *q = p->parent;
        Node *r = q->parent;

        if ( ( q->right = p->left ) != NULL )
            q->right->parent = q;

        p->left = q;
        q->parent = p;

        if ( ( p->parent = r ) != NULL )
        {
            if ( r->left == q )
                r->left = p;
            else
                r->right = p;
        }
    }

    void splay( Node* &p )
    {
        while ( !p->isRoot() )
        {
            Node *q = p->parent;

            if ( q->isRoot() )
            {
                if ( q->left == p )
                    rotateRight( p );
                else
                    rotateLeft( p );
            }
            else
            {
                Node *r = q->parent;

                if ( r->left == q )
                {
                    if ( q->left == p )
                    {
                        rotateRight( p );
                        rotateRight( p );
                    }
                    else
                    {
                        rotateLeft( p );
                        rotateRight( p );
                    }
                }
                else
                {
                    if ( q->left == p )
                    {
                        rotateRight( p );
                        rotateLeft( p );
                    }
                    else
                    {
                        rotateLeft( p );
                        rotateLeft( p );
                    }
                }
            }
        }
    }

    Node* expose( Node* p )
    {
        Node* last = NULL;

        for ( Node* x = p; x != NULL; x = x->parent )
        {
            splay( x );
            x->left = last;
            last = x;
        }

        splay( p );

        return last;
    }

    int findRoot( int x )
    {
        expose( Nodes[x] );

        while ( Nodes[x]->right != NULL ) Nodes[x] = Nodes[x]->right;

        return Nodes[x]->id;
    }

    void link( int x, int y )
    {
        expose( Nodes[x] );
        Nodes[x]->parent = Nodes[y];
    }

    Node** Nodes;
    int N;

    LinkCutTree(const int _N)
    {
        N = _N;
        Nodes = new Node*[_N + 1];

        for ( int i = 1; i <= N; ++i )
            Nodes[i] = new Node(i);
    }
};

int N, M;

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

    in >> N >> M;

    LinkCutTree T( N );

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

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

    ///afis();

    return 0;
}