Cod sursa(job #969685)

Utilizator mihai995mihai995 mihai995 Data 5 iulie 2013 00:14:24
Problema Paduri de multimi disjuncte Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.77 kb
#include <assert.h>
#include <stdio.h>

typedef enum{
    ALREADY_MERGED,
    SUCCESS
} disjoint_set_feedback;

typedef struct{
    int size;
    int* rank;
    int* parent;
} disjoint_set;

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

int _disjoint_set_get_father(disjoint_set* forest, int node){
    if (node == forest -> parent[node])
        return node;

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

    return forest -> parent[node];
}

int disjoint_set_father(disjoint_set* forest, int node){
    _disjoint_set_assert(forest, node);

    return _disjoint_set_get_father(forest, node);
}

disjoint_set_feedback disjoint_set_merge(disjoint_set* forest, int first_node, int second_node){
    _disjoint_set_assert(forest, first_node);
    _disjoint_set_assert(forest, second_node);

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

    if (first_node == second_node)
        return ALREADY_MERGED;

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

    return SUCCESS;
}

disjoint_set* disjoint_set_new(int size){
    disjoint_set* forest = malloc( sizeof(disjoint_set) );

    forest -> parent = (int*)malloc(size * sizeof(int));
    forest -> rank = (int*)malloc(size * sizeof(int));
    forest -> size = size;

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

    return forest;
}

int disjoint_set_brothers(disjoint_set* forest, int first_node, int second_node){
    _disjoint_set_assert(forest, first_node);
    _disjoint_set_assert(forest, second_node);

    first_node = _disjoint_set_get_father(forest, first_node);
    second_node = _disjoint_set_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);

    disjoint_set* forest = disjoint_set_new(n + 1);

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

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

    fclose(fin);
    fclose(fout);

    return 0;
}