最小生成树

来源:互联网 发布:unity编程 编辑:程序博客网 时间:2024/06/07 06:38
#include <stdio.h>#include <algorithm>#define MAX_NODE 100#define MAX_ARC 1000typedef struct ARC // 边结构体{    int s, e, w;}ARC, *PARC;int father[MAX_NODE]; // 节点i的根节点为father[i]int son[MAX_NODE]; // 节点i的孩子有son[i]个ARC edge[MAX_ARC]; // 记录边int vn, an; // 顶点数 边数int cmp(ARC x, ARC y) // 比较函数{    return x.w < y.w;}int unionSearch(int x) // 并查集查找根节点{    return x == father[x] ? x : (father[x] = unionSearch(father[x]));}int join(int s, int e) // 并查集{    int root1 = unionSearch(s); // 查找s的根节点    int root2 = unionSearch(e); // 查找e的根节点    if (root1 == root2)    {        return 0; // s e 在同一组    }    if (son[root1] > son[root2]) // 为了平衡并查集    {        father[root2] = root1;        son[root1] += son[root2];    }    else    {        father[root1] = root2;        son[root2] += son[root1];    }    return 1;}void kruskal(){    int i, cnt = 1, flag = 0, weight = 0;    printf("请输入点数和边数以空格隔开: ");    scanf("%d%d", &vn, &an);    for (i = 1; i <= vn; i++) // 初始化并查集    {        father[i] = i;        son[i] = 1;    }    printf("请输入边的信息(s e w)以空格隔开: \n");    for (i = 1; i <= an; i++)    {        scanf("%d%d%d", &edge[i].s, &edge[i].e, &edge[i].w);    }    std::sort(edge + 1, edge + an + 1, cmp); // 按权值排序    for (i = 1; i < an; i++)    {        if (join(edge[i].s, edge[i].e)) // 加入端点        {            cnt++; // 加入成功点数加一            weight += edge[i].w; // 记录权值和            printf("%d -----> %d  :  %d\n", edge[i].s, edge[i].e, edge[i].w);        }        if (cnt == vn) // 存在一颗vn个顶点的树        {            flag = 1; // 找到最小生成树            break;        }    }    if (flag)    {        printf("%d\n", weight);    }    else    {        printf("不能生成树!\n");    }}int main(){    kruskal();    return 0;}
0 0
原创粉丝点击