Pagini recente » Cod sursa (job #1959614) | Cod sursa (job #1983258) | Cod sursa (job #1814476) | Cod sursa (job #2548606) | Cod sursa (job #2805618)
#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;
}