Pagini recente » Cod sursa (job #693971) | Cod sursa (job #1664737) | Cod sursa (job #1752806) | Cod sursa (job #2990186) | Cod sursa (job #3241568)
#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;
}