Cod sursa(job #2805618)

Utilizator RoberttoPopescu Paullo Robertto Karloss Robertto Data 21 noiembrie 2021 15:46:32
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
#include <fstream>
#include <algorithm>
#include <vector>

using namespace std;

fstream fin("disjoint.in");
ofstream fout("disjoint.out");

int costAPM, tata[200001], inaltime[200001];

struct muchie {
    int tipOperatie, sursa, destinatie;
} u[400001];

// complexitatea pentru a gasii reprezentantul este O(reprezentant)
int reprezentant_tata(int nod) {///cautam nodul sursa ,nu tatal direct
    while (tata[nod] != nod)
        nod = tata[nod];
    return nod;
}

// regula: intotdeauna vom unii arborele de inaltime mai mica de arborele cu inaltime mai mare
void reuneste(int tataSursa, int tataDestinatie) {
    if (inaltime[tataSursa] > inaltime[tataDestinatie])
        // daca subarborele tataSursa are inaltimea mai mare decat tataDestinatie
        tata[tataDestinatie] = tataSursa;
        // leg subarborele de inaltime mai mica (in cazul nostru tataDestinatie)
        // de subarborele de inaltime mai mare (in cazul nostru tataSursa)
    else if (inaltime[tataSursa] < inaltime[tataDestinatie])
        tata[tataSursa] = tataDestinatie;
    else if (inaltime[tataSursa] == inaltime[tataDestinatie]) {
        // daca au aceeasi inaltime
        tata[tataSursa] = tataDestinatie; // leg subarborele tataSursa de subarborele tataDestinatie
        inaltime[tataDestinatie]++; // dupa ce le-am legat inaltimea arborelui meu creste
        // de exemplu am 2 subarbori de inaltime 2, arborele meu, dupa ce i-am unit va avea inaltimea 3.
        // pot unii fie primul subarbore de al doilea sau invers
        // dupa ce i-am unit arborele meu va avea inaltimea unui subarbore + 1
        // de ce? atunci cand unesc doi subarbori, eu adaug ca fiu al radacinii subarborelui meu, celalalt subarbore
    }
}

void kruskal() {
    vector<pair<int, int>> apm;
    int nrNoduri, nrMuchii;
    fin >> nrNoduri >> nrMuchii;
    for (int i = 1; i <= nrMuchii; i++)
        fin >> u[i].tipOperatie >> u[i].sursa >> u[i].destinatie; // tip operatie
//    sort(u + 1, u + nrMuchii + 1, comp); // sortez crescator muchiile dupa cost
    for (int i = 1; i <= nrNoduri; i++) { // initializare complexitate O(n)
        tata[i] = i;
        inaltime[i] = 0;
    }
    for (int i = 1; i <= nrMuchii; i++) {
        int tataSursa = reprezentant_tata(u[i].sursa); // caut reprezentantul nodului sursa curent
        int tataDestinatie = reprezentant_tata(u[i].destinatie); // caut reprezentantantul nodului destinatie curent
        if (u[i].tipOperatie == 1) {
            reuneste(tataSursa, tataDestinatie);
        } else if (tataSursa == tataDestinatie) {
            // daca am acelasi tata inseamna ca fac parte din aceeasi multime
            fout << "DA\n";

        } else
            fout << "NU\n";
    }
}

int main() {
    kruskal();
    return 0;
}