并查集(非递归+结构体)

来源:互联网 发布:电脑信号屏蔽软件 编辑:程序博客网 时间:2024/05/22 03:43
#include <stdio.h>#define MAX_NODE 1001 // 节点数typedef struct{    int father; // 根节点    int size; // 以该节点为根的树的大小    double date; // 节点信息}UFNode;UFNode uf[MAX_NODE]; // 并查集/*    @function:  查找节点son的根节点    @param:     son-->需要查找的节点    @return:    int-->son节点的根节点*/int findFather(int son){    int rt = son, s = son, t;    while (rt != uf[rt].father) // 寻找son的根节点rt    {        rt = uf[rt].father; // 往上寻找,直到找到根节点    }    while (rt != s) // 未压缩到根节点    {        t = uf[s].father; // 记录s的父节点        uf[s].father = rt; // 将s压缩成rt的的子节点        s = t; // 为压缩s的父节点做准备    }    return rt; // 返回son的根节点}/*    @function:  合并节点 p1 p2    @param:     p1-->需合并的第一个点                p2-->需合并的第二个点    @return:    int-->需要合并返回1,不需要合并返回0*/int unionNode(int p1, int p2){    int p1rt = findFather(p1); // 查找p1根节点    int p2rt = findFather(p2); // 查找p2根节点    if (p1rt == p2rt) // 根节点相同,不需要合并    {        return 0; // 返回0    }    if (uf[p1rt].size < uf[p2rt].size) // p1rt节点数小于p2rt    {        uf[p1rt].father = p2rt; // p1rt成为p2rt子树        uf[p2rt].size += uf[p1rt].size; // p2rt节点数增加size[p1rt]个    }    else // p1rt节点数大于等于p2rt    {        uf[p2rt].father = p1rt; // p2rt成为p1rt子树        uf[p1rt].size += uf[p2rt].size; // p1rt节点数增加size[p2rt]个    }    return 1;}/*    @function:  初始化并查集    @param:     sz-->并查集大小    @return:    int-->初始化成功返回1,失败返回0*/int initUnionFind(int sz){    if (sz >= MAX_NODE || sz < 0)    {        return 0;    }    for (int i = 0; i <= sz; ++i)    {        uf[i].father = i;        uf[i].size = 1;        uf[i].date = 0.0;    }    return 1;}int main(){    int n, m, s, t, cnt;    while (scanf("%d%d", &n, &m) == 2)    {        if (initUnionFind(n))        {            cnt = 0;            for (int i = 0; i < m; ++i)            {                scanf("%d%d", &s, &t);                if (unionNode(s, t))                {                    cnt++;                }            }            printf("连通块数量: %d\n", n - cnt);        }    }    return 0;}
0 0
原创粉丝点击