Cod sursa(job #2846712)

Utilizator paul911234vaida paul paul911234 Data 9 februarie 2022 16:18:52
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;

vector<int> father(1e5 + 1), degree(1e5 + 1);

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

int find(int node) {
		int root;
		// fac o parcurgere in cautarea radacinei prin "vectorul de tati"
		for (root = node; father[root] != root; root = father[root]);

		//acplic compresia drumurilor astfel incat toate nodurile sa aibe aceaiasi radacina
		//asa parcurgerea de sus va fi mai lenta
		while(father[node] != node) {
				int auxNode = father[node];
				father[node] = root;
				node = auxNode;
		}
		return root;
}

void unite(int x, int y) {
		// unesc radacina arborelui "x"
		if (degree[x] > degree[y]) {
				father[y] = x;
		} else {
				father[x] = y;
		}
		//if (degree[x] == degree[y]) {
			//	degree[y] += 1;
		//}
}

int main() {
		//cin.tie(0), cout.tie(0), ios :: sync_with_stdio(0);
		int n, m;
		fin >> n >> m;
		for (int i = 1; i <= n; ++i) {
				father[i] = i;
				degree[i] = 1;
		}
		while (m--) {
				int operation, x, y;
				fin >> operation >> x >> y;
				if (operation == 2) {
						// daca nodurile x si y au aceiasi radacina atunci fac parte din aceiasi componenta conexa
						fout << ((find(x) == find(y))? "DA": "NU") << '\n';
				} else {
						unite(find(x), find(y)); // cu acest apel de functie voi uni radacinile celor 2 arbori
						//deoarece find(node), pointeaza spre radacina si face si compresia drumurilor in acelasi timp
				}
		}
}