树的算法_1,并查集

来源:互联网 发布:保法止效果知乎 编辑:程序博客网 时间:2024/05/22 14:26
#include <stdio.h>//节点个数#define ELEM_C 10//开始先假设每一个节点都是单独的一棵树,下标(节点)对应的值为它的父节点//例如:节点0的根节点就是其本身:elems[0] == 0elems[4] == 4int elems[ELEM_C] = {0,1,2,3,4,5,6,7,8,9};//得到当前节点的根节点int getRoot(int elem){    if (elems[elem] == elem)        return elem;    else {        //压缩路径,每次都在返回根节点前把elem的父节点改成根节点        //这样以后就可以减少递归的深度,从而提高算法效率(其实直接return getRoot(elems[elem]);也可以,只不过递归的深度会越来越大)        elems[elem] = getRoot(elems[elem]);        return elems[elem];    }}//分别求出两个节点的根,如果不是同一个根节点(即不属于同一个集合),则把其中一个根挂到另一个根下void merge(int elem_1, int elem_2){    int root_1 = getRoot(elem_1);    int root_2 = getRoot(elem_2);    if (root_1 != root_2)        elems[root_2] = root_1;}void main() {    int unionCount, u, v, i, sum=0;    //输入节点之间的关联次数    scanf("%d", &unionCount);    for (i = 0; i < unionCount; ++i) {        //合并树集合        scanf("%d %d", &u, &v);        merge(u, v);    }    //计算出一共有多少个集合    for (i = 0; i < ELEM_C; ++i) {        if (elems[i] == i)            sum++;    }    printf("have %d set", sum);}
测试如下:91 23 45 24 62 68 79 71 62 4have 3 set