Cod sursa(job #3241568)

Utilizator filipinezulBrain Crash filipinezul Data 31 august 2024 15:40:36
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <bits/stdc++.h>
using namespace std;

class DisjointSet {
    private: 
        // root[i] = radacina arborelui din care face parte i.
        vector<int> root;

        // size[i] = numarul de noduri ale arborelui in care se afla i acum.
        vector<int> size;
    
    public:
        // se initializeaza n paduri.
        DisjointSet(int n)
            : root(n + 1)
            , size(n + 1) {
            
            // fiecare padure contine un nod initial.
            for (int node = 1; node <= n; ++node) {
                root[node] = node;
                size[node] = 1;
            }
        }

        // returneaza radacina arborelui din care face parte node.
        int setOf(int node) {
            // daca node este radacina, atunci am gasit raspunsul.
            if (node == root[node]) {
                return node;
            }

            // altfel, urcam in sus din "radacina in radacina",
            // actualizand pe parcurs radacinile pentru nodurile atinse.
            //! path compresion
            root[node] = setOf(root[node]);
            return root[node];
        }

        // reuneste arborii lui x si y intr-un singur arbore,
        //! folosind euristica de reuniune a drumurilor dupa rank.
        void unionByRank(int x, int y) {
            // obtinem radacinile celor 2 arbori
            int rx = setOf(x), ry = setOf(y);

            // arborele mai mic este atasat la radacina arborelui mai mare.
            if (size[rx] <= size[ry]) {
                size[ry] += size[rx];
                root[rx] = ry;

            } else {
                size[rx] += size[ry];
                root[ry] = rx;
            }
        }
    };

class Task {
 public:
    void solve() {
        read_input();
        print_output();
    }

 private:
    int n, m;
    vector<string> results;

    DisjointSet* dsu;

    void read_input() {
        ifstream fin("disjoint.in");
        fin >> n >> m;

        dsu = new DisjointSet(n);

        for (int i = 0, code, x, y; i < m; ++i) {
            fin >> code >> x >> y;
            get_result(code, x, y);
        }
        

        fin.close();
    }

    void get_result(int code, int x, int y) {
        if (code == 1) {
            dsu->unionByRank(x, y);
            return;
        }

        if (dsu->setOf(x) == dsu->setOf(y)) {
            results.push_back("DA");
            return;
        }

        results.push_back("NU");
    }

    void print_output() {
        ofstream fout("disjoint.out");
        
        for (const auto& result : results) {
            fout << result << "\n";
        } 

        fout.close();
        delete dsu;
    }
};

int main() {
    ios::sync_with_stdio(false);
    auto* task = new (nothrow) Task();

    if (!task) {
        cerr << "new failed\n";
        return -1;
    }

    task->solve();
    delete task;

    return 0;
}