Pagini recente » Cod sursa (job #1786364) | Cod sursa (job #2338308) | Cod sursa (job #2623237) | Cod sursa (job #675888) | Cod sursa (job #3278828)
#include <fstream>
using namespace std;
ifstream fin("disjoint.in");
ofstream fout("disjoint.out");
// dad[x] - cine este "tatal" lui x -> ce element este in aceeasi multime cu x
// x: 1 2 3 4
// vrem sa avem in dad[x] un element comun
// initial, pentru fiecare element, dad[x] = x
// pentru 2 elemente, x si y, ne uitam in dad[x] si dad[y]
// daca cele doua valori sunt diferite, se face un union (elementul mai mare va avea in dad valoarea mai mica)
// dad[x] = x, dad[y], x < y -> dad[y] = x
// la un moment dat
// 1 -> 2 -> 3 -> 4 -> 5
// dad[5] = 4
// dad[4] = 3
// dad[3] = 2
// dad[2] = 1
// dad[1] = 1
/*
1 -> 2
-> 3
-> 4
-> 5 -> 6
-> 7
*/
/*
1 -> 2
-> 3
-> 4
-> 5
-> 6
-> 7
*/
/*
1 -> 2
-> 3
-> 4
-> 5
-> 6
-> 7
-> 8
-> 9
*/
const int NMAX = 1e5 + 1;
int dad[NMAX];
// complexitatea O(1) amortizat
int find(int x) // are rolul de a gasi "cel mai de sus" tata
{
if (dad[x] == x)
return x;
return dad[x] = find(dad[x]);
}
// de fapt, cand facem o operatie de tip 2, apelam find() pentru ambele numere
// daca find returneaza acelasi rezultat, atunci fac parte din aceeasi multime
// acum, cand facem o operatie de tip 1 (union), de fapt va trebui sa unim find(x) si find(y), adica sefii de sus
// unirea se face prin dad[find(y)] = find(x)
int n, m;
int main()
{
fin >> n >> m;
// initializarea
for (int i = 1; i <= n; ++i)
dad[i] = i;
int c, x, y;
while (m--)
{
fin >> c >> x >> y;
// union
int nx = find(x);
int ny = find(y);
if (c == 1)
{
// trebuie sa respecta ordinea
if (nx < ny)
dad[ny] = nx;
else
dad[nx] = ny;
}
else
{
if (nx == ny)
fout << "DA" << '\n';
else
fout << "NU" << '\n';
}
}
return 0;
}