Cod sursa(job #969614)

Utilizator mihai995mihai995 mihai995 Data 4 iulie 2013 20:03:18
Problema Paduri de multimi disjuncte Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.9 kb
#include <assert.h>
#include <stdio.h>

typedef struct{
    int rank, parent;
} _disjoint_set_forest_node;

typedef struct{
    _disjoint_set_forest_node* forest;
    int size;
} _disjoint_set_forest;

void _disjoint_set_forest_assert(_disjoint_set_forest* forest, int node){
    assert(0 <= node && node < forest -> size);
}

int _disjoint_set_forest_get_father(_disjoint_set_forest* forest, int node){
    if (node == forest -> forest[node].parent)
        return node;

    forest -> forest[node].parent = _disjoint_set_forest_get_father(forest, forest -> forest[node].parent);

    return forest -> forest[node].parent;
}

int _disjoint_set_forest_father(_disjoint_set_forest* forest, int node){
    _disjoint_set_forest_assert(forest, node);

    return _disjoint_set_forest_father(forest, node);
}

void _disjoint_set_forest_merge(_disjoint_set_forest* forest, int first_node, int second_node){
    _disjoint_set_forest_assert(forest, first_node);
    _disjoint_set_forest_assert(forest, second_node);

    first_node = _disjoint_set_forest_get_father(forest, first_node);
    second_node = _disjoint_set_forest_get_father(forest, second_node);

    if (first_node == second_node)
        return;

    if (forest -> forest[first_node].rank > forest -> forest[second_node].rank){
        forest -> forest[second_node].parent = first_node;
        forest -> forest[first_node].rank += forest -> forest[second_node].rank;
    } else {
        forest -> forest[first_node].parent = second_node;
        forest -> forest[second_node].rank += forest -> forest[first_node].rank;
    }
}

_disjoint_set_forest* _disjoint_set_forest_new(int size){
    _disjoint_set_forest* forest = (_disjoint_set_forest*)malloc(sizeof(_disjoint_set_forest));
    forest -> forest = (int*)malloc(size * sizeof(_disjoint_set_forest_node));
    forest -> size = size;

    int i;
    for (i = 0 ; i < size ; i++){
        forest -> forest[i].rank = 1;
        forest -> forest[i].parent = i;
    }

    return forest;
}

int _disjoint_set_forest_brothers(_disjoint_set_forest* forest, int first_node, int second_node){
    _disjoint_set_forest_assert(forest, first_node);
    _disjoint_set_forest_assert(forest, second_node);

    first_node = _disjoint_set_forest_get_father(forest, first_node);
    second_node = _disjoint_set_forest_get_father(forest, second_node);

    return (first_node == second_node);
}

int main(){
    FILE* fin = fopen("disjoint.in", "r");
    FILE* fout = fopen("disjoint.out", "w");

    int n, m, t, x, y;

    fscanf(fin, "%d%d", &n, &m);

    void* forest = _disjoint_set_forest_new(n + 1);

    while (m--){
        fscanf(fin, "%d%d%d", &t, &x, &y);

        if (t == 1)
            _disjoint_set_forest_merge(forest, x, y);
        else
            if (_disjoint_set_forest_brothers(forest, x, y))
                fprintf(fout, "DA\n");
            else
                fprintf(fout, "NU\n");
    }

    fclose(fin);
    fclose(fout);

    return 0;
}