Cod sursa(job #1699627)

Utilizator cosmin79Carabet Cosmin Andrei cosmin79 Data 7 mai 2016 23:29:00
Problema Paduri de multimi disjuncte Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 2.17 kb
#include <cstdio>
const int NMAX = 100505;

int N, M, par[NMAX], rnk[NMAX];

void init() {
    for (int i = 1; i <= N; i++) {
        par[i] = i;
    }
}

inline void pathCompression(int startNode, int endNode) {
    int aux;
    while (startNode != endNode) {
        aux = par[startNode];
        par[startNode] = endNode;
        startNode = aux;
    }
}

inline bool isRoot(int node) {
    return par[node] == node;
}

bool sameTree(int x, int y) {
    int endX = x, endY = y;
    while (!isRoot(endX) && !isRoot(endY)) {
        if (rnk[endX] < rnk[endY]) {
            endX = par[endX];
        } else {
            endY = par[endY];
        }
    }

    pathCompression(x, par[endX]);
    pathCompression(y, par[endY]);
    return par[endX] == par[endY];
}

void unite(int x, int y) {
    int endX = x, endY = y;
    while (endX != endY) {
        if (isRoot(endX) && rnk[endX] < rnk[endY]) {
            par[endX] = endY;
            break ;
        } else if (isRoot(endY) && rnk[endY] < rnk[endX]) {
            par[endY] = endX;
            break ;
        } else if (isRoot(endX) && isRoot(endY) && rnk[endX] == rnk[endY]) {
            par[endX] = endY;
            rnk[endY]++;
            if (!isRoot(endY) && rnk[par[endY]] == rnk[endY]) {
                int aux = endY;
                while (!isRoot(aux)) {
                    rnk[par[aux]]++;
                    aux = par[aux];
                }
                pathCompression(endY, aux);
            }
            break ;
        }

        if (rnk[endX] < rnk[endY] || (rnk[endX] == rnk[endY] && isRoot(endY))) {
            endX = par[endX];
        } else {
            endY = par[endY];
        }
    }

    pathCompression(x, par[endX]);
    pathCompression(y, par[endY]);
}

int main() {
    freopen("disjoint.in", "r", stdin);
    freopen("disjoint.out", "w", stdout);

    scanf("%d%d", &N, &M);
    init();
    int type, x, y;
    for (int i = 1; i <= M; i++) {
        scanf("%d%d%d", &type, &x, &y);
        if (type == 1) {
            unite(x, y);
        } else {
            if (sameTree(x, y)) {
                printf("DA\n");
            } else {
                printf("NU\n");
            }
        }
    }
    return 0;
}