arhipelag

Na velikom arhipelagu ima \(n\) ostrva označenih brojevima \(1,2,\ldots,n\). U početku nema mostova i svako ostrvo je samostalno. Tokom vremena događaju se operacije:

Vaš zadatak je da obradite niz operacija i da za svaku informativnu operaciju ispišete odgovor.

Opis ulaza

Sa standardnog ulaza se unosi broj ostrva \(n\) (\(1 \leq n \leq 10^5\)) i broj upita \(m\) (\(1 \leq m \leq 10^5\)).

U sledećih \(m\) redova, unosi se po jedna operacija oblika:

Opis izlaza

Za svaku operaciju tipa P, V ili K ispišite po jedan red sa traženim odgovorom.

Primer

Ulaz

7 11 K U 1 2 U 2 3 V 2 P 1 4 U 4 5 U 6 7 K U 3 4 P 5 1 V 6

Izlaz

7 3 NE 3 DA 2

Objašnjenje

Na početku ima 7 odvojenih ostvra \(\{1\}, \{2\}, \{3\}, \{4\}, \{5\}, \{6\}, \{7\}\).

Rešenje

Opis glavnog rešenja

U ovom bloku se opisuje glavno rešenje zadatka.

#include <iostream>
#include <vector>

using namespace std;

vector<int> parent;
vector<int> sz;

int groups;

void UF_init(int n)
{
    parent.resize(n + 1);
    sz.resize(n + 1, 1);

    for (int i = 1; i < n + 1; i++) {
        parent[i] = i;
    }

    groups = n;
}

int UF_find(int x)
{
    while (x != parent[x]) {
        parent[x] = parent[parent[x]];
        x = parent[x];
    }

    return x;
}

void UF_union(int x, int y)
{
    int fx = UF_find(x);
    int fy = UF_find(y);

    if (fx == fy) return;

    if (sz[fx] < sz[fy]) {
        swap(fx, fy);
    }
    parent[fy] = fx;
    sz[fx] += sz[fy];

    groups--;
}

bool UF_same(int x, int y)
{
    return UF_find(x) == UF_find(y);
}

int UF_size_of(int x)
{
    return sz[UF_find(x)];
}

int UF_size()
{
    return groups;
}

int main() 
{
    int n, m; cin >> n >> m;

    UF_init(n);

    while(m--) {
        char op; cin >> op;

        if (op == 'U') {
            int x, y; cin >> x >> y;
            UF_union(x, y);
        } else if (op == 'P') {
            int x, y; cin >> x >> y;
            cout << (UF_same(x, y) ? "DA" : "NE") << endl;
        } else if (op == 'V') {
            int x; cin >> x;
            cout << UF_size_of(x) << endl;
        } else if (op == 'K') {
            cout << UF_size() << endl;
        }
    }

    return 0;
}
#include <iostream>
#include <vector>

using namespace std;

vector<int> parent;
vector<int> sz;

int groups;

void init(int n)
{
    parent.resize(n + 1);
    sz.resize(n + 1, 1);

    for (int i = 1; i < n + 1; i++) {
        parent[i] = i;
    }

    groups = n;
}

void uni(int x, int y)
{
    int fx = parent[x];
    int fy = parent[y];

    if (fx == fy) {
        return;
    }

    for (int i = 1; i < parent.size(); i++) {
        if (parent[i] == fy) {
            parent[i] = fx;
        }
    }

    sz[fx] += sz[fy];

    groups--;
}

bool same(int x, int y)
{
    return parent[x] == parent[y];
}

int size_of(int x)
{
    return sz[parent[x]];
}

int size()
{
    return groups;
}

int main() 
{
    int n, m; cin >> n >> m;

    init(n);

    while(m--) {
        char op; cin >> op;

        if (op == 'U') {
            int x, y; cin >> x >> y;
            uni(x, y);
        } else if (op == 'P') {
            int x, y; cin >> x >> y;
            cout << (same(x, y) ? "DA" : "NE") << endl;
        } else if (op == 'V') {
            int x; cin >> x;
            cout << size_of(x) << endl;
        } else if (op == 'K') {
            cout << size() << endl;
        }
    }

    return 0;
}