Cod sursa(job #1943149)

Utilizator rares00Foica Rares rares00 Data 28 martie 2017 12:58:55
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.13 kb
#include <iostream>
#include <fstream>
#define LN 100000
using namespace std;
ifstream in("disjoint.in");
ofstream out("disjoint.out");

int n,m;
struct nod{
    int inf;
    int rang;
    struct nod *urm;
}*a[LN+2],*p;

void makeSet(int x)
{
    p=new nod;
    p->inf=x;
    p->rang=0;
    p->urm=p;
    a[x]=p;
}

int findSet(int x)
{
    int temp[LN],vf=0;
//determina reprezentantul multimii din care face parte nodul x
    struct nod *ant=a[x];
        p=a[x]->urm;
    while(ant->inf != p->inf)
    {
        temp[++vf]=ant->inf;
        ant=p;
        p=p->urm;
    }
//compresia caii
    while(vf>0)
    {
        a[temp[vf]]->urm=ant;
        vf--;
    }
//returneaza reprezentantul
    return ant->inf;
}

void reuneste(int x,int y)
{
    int mx=findSet(x);
    int my=findSet(y);
    if(mx!=my) //reuneste numai daca nodurile fac parte din multimi diferite
    {
        if(a[mx]->rang == a[my]->rang) //daca multimile au acelasi rang
        {
            a[mx]->rang++;
            a[my]->urm = a[mx];
        }
        else //multimile au ranguri diferite
        {
            //adauga multimea cu rang mai mic la cea cu rang mai mare
            if(a[mx]->rang > a[my]->rang)
                a[my]->urm = a[mx];
            else
                a[mx]->urm = a[my];
        }
    }
}

int main()
{
    in>>n>>m;
//creeaza cele n multimi/arbori diferiti
    for(int i=1;i<=n;++i)
        makeSet(i);
//efectueaza operatiile cerute
    int cod,x,y;
    for(int i=1;i<=m;++i)
    {
        in>>cod>>x>>y;
        if(cod==1) //reuneste multimile nodurilor x si y
        {
            reuneste(x,y);
        }
        else if(cod==2) //verifica daca nodurile x si y sunt in aceeasi multime
        {
            if(findSet(x)==findSet(y))
                out<<"DA\n";
            else out<<"NU\n";
        }
    }

    /*for(int i=1;i<=n;++i)
        cout<<findSet(i)<<" ";
    cout<<"\n";
    int a,b;
    while(true){
        cin>>a>>b, reuneste(a,b);
        for(int i=1;i<=n;++i)
            cout<<findSet(i)<<" ";
        cout<<"\n";
    }*/
    return 0;
}