最小生成树 oj 2144

本文深入探讨了最小生成树算法的实现原理,通过快速排序和并查集操作,确保从一组边中选取n-1条边连接n个点,使得总花费最小且不形成环路。介绍了如何使用C语言实现这一算法,包括快速排序、初始化并查集、查找根节点和合并两个集合等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

n个点,有n-1条边就可连通, 总花费最小要选择 花费小 且 不会使各点连环 的 n-1条边

快排对边长(费用)进行排序, merge函数中判断会不会成环, 边数达到n-1 break;

#include <stdio.h>
#include <stdlib.h>
int m, n, f[110];
struct node
{
    int u, v, w;
}a[10010], key;
void qs(struct node a[],int l, int r)
{
    int i = l, j = r;
    key = a[l];
    if(l >= r) return ;
    while(i < j)
    {
        while(i < j && a[j].w >= key.w) j--;
        a[i] = a[j];
        while(i < j && a[i].w <= key.w) i++;
        a[j] = a[i];
    }
    a[i] = key;
    qs(a, l, i-1);
    qs(a, i+1, r);
}
void init(int f[])
{
    int i;
    for(i = 1; i <= n; i++)
    {
        f[i] = i;
    }
}
int getf(int u)
{
    if(f[u] == u) return u;
    f[u] = getf(f[u]);
    return f[u];
}
int merge(int u, int v)
{
    int x = getf(u), y = getf(v);
    if(x != y)
    {
        f[y] = x;
        return 0;
    }
    else return 1;
}
int main()
{
    int i;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        init(f);
        for(i = 0; i < m; i++)
        {
            scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].w);
        }
        qs(a, 0, m-1);
        int num = 0, cost = 0;
        for(i = 0; i < m; i++)
        {
            if(num == n-1)
                break;
            if(merge(a[i].u, a[i].v) == 0)
            {
                num++;
                cost += a[i].w;
            }
        }
        printf("%d\n", cost);
    }
    return 0;
}


/***************************************************
User name: jk170536张璐
Result: Accepted
Take time: 16ms
Take Memory: 248KB
Submit time: 2018-08-21 19:50:03
****************************************************/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值