Cod sursa(job #1025348)

Utilizator mazaandreiAndrei Mazareanu mazaandrei Data 9 noiembrie 2013 20:31:01
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.67 kb
#include<fstream>
#include<cstring>
#define DIM 10000
using namespace std;
//Varianta 2: euristice (arbore minim se aduna la cel maxim, + compresia drumurilor
int t[100001];
int h[100001];
int r[100001];
char buff[10000];
int n,m,x,y,tip,poz;
ifstream in("disjoint.in"); ofstream out("disjoint.out");
void cit(int &nr){
    nr=0;
    while('0'>buff[poz] || buff[poz]>'9'){
        if(++poz==DIM) in.read(buff,DIM),poz=0;
    }
    while('0'<=buff[poz] && buff[poz]<='9'){
        nr=nr*10+buff[poz]-'0';
        if(++poz==DIM) in.read(buff,DIM),poz=0;
    }
}
int radacina(int x){
    int nr=0;
    while(t[x]!=0){
        r[++nr]=x; //Mergem recursiv din tata in tata pana ajungem la radacina unui arbore. Retinem drumul
        x=t[x];
    }
    for(int i=1;i<=nr;++i) t[r[i]]=x; //Toate elem. din drum le legam direct de tata (au aceeasi radacina oricum)
    return x;
}
void reunit(int x, int y){
    int tx=radacina(x);
    int ty=radacina(y);
    if(h[tx]>h[ty]){ //cel mai mic se adauga la cel mai mare
        h[tx]+=h[ty]; //se aduna nr. de elem din fiecare  si se leaga radacinile lor formand astfel un singur arbore (multime)
        t[ty]=x;
    }
    else{
        h[ty]+=h[tx];
        t[tx]=y;
    }
}

int main(){
    cit(n); cit(m);
    for(int i=1;i<=n;++i) h[i]=1;
    for(int i=1;i<=m;++i){
        cit(tip); cit(x); cit(y);
        if(tip==1) reunit(x,y); //multimile avand elementele x si y se reunesc.
        else{
            if(radacina(x)==radacina(y)) out<<"DA\n"; //Daca cele 2 noduri au aceeasi radacina =>sunt in acelasi arbore (multime)
            else out<<"NU\n";
        }
    }
    out.close();
    return 0;
}