Cod sursa(job #2675281)

Utilizator MicuMicuda Andrei Micu Data 21 noiembrie 2020 12:16:20
Problema Paduri de multimi disjuncte Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.72 kb
#include <bits/stdc++.h>

using namespace std;

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

class UnionFind
{
  int size;

  //* the size of each component
  int *sz;

  //* the parent of node i, if id[i] = i, i is the root of the component
  int *id;

public:
  UnionFind(int size)
  {
    size = size;

    sz = new int[size];
    id = new int[size];

    for (int i = 0; i < size; i++)
    {
      //* initially, each node is a 1-element component
      id[i] = i;
      sz[i] = 1;
    }
  }

  //* finds the root of the component containing p
  int find(int p)
  {
    int root = p;
    while (id[root] != root)
    {
      root = id[root];
    }

    //* we perform path compression, linking every node along the path to the root
    while (p != root)
    {
      int next = id[p];
      id[p] = root;
      p = next;
    }

    return root;
  }

  bool connected(int p, int q)
  {
    //* two nodes are connected if they have the same root
    return find(p) == find(q);
  }

  void unify(int p, int q)
  {
    int root1 = find(p);
    int root2 = find(q);

    //* p & q are already unified => nothing to do
    if (root1 == root2)
      return;

    //* we make the smaller component a child of the larger one
    if (sz[root1] > sz[root2])
    {
      id[root2] = root1;
      sz[root1] += sz[root2];
    }
    else
    {
      id[root1] = root2;
      sz[root2] += sz[root1];
    }
  }
};

int main()
{
  int n, m;
  in >> n >> m;
  UnionFind u(n);
  for (int i = 0; i < m; i++)
  {
    int op_type, x, y;
    in >> op_type >> x >> y;
    switch (op_type)
    {
    case 1:
      u.unify(x, y);
      break;

    case 2:
      out << (u.connected(x, y) ? "DA\n" : "NU\n");
      break;

    default:
      break;
    }
  }
  return 0;
}