并查集解决最优灌溉问题(最小生成树问题)

以下都是个人理解,解释别人写好的代码,随便写写
1.什么是并查集
是一种数据结构,其实也就是一种树结构
把i节点的父节点保存在array[i]数组里,根节点的父节点为自身。
对于这种数据结构可以实现的功能有两个
(1)查找一个节点的根节点,通过数组里保存的父节点一层一层向上查找,知道找到一个节点的父节点是自己,那这个节点就是根节点了。
(2)判断两个节点是否属于一个树,找到这两个节点的根节点进行比较,如果根节点相同,这两个节点就属于一个树,如果不相同,就不属于一个树。
(3)把两个树合并,在功能(2)中如果判断出两个节点不属于一个树,想要把这两个树合并,就把其中一个节点的根节点的父节点从自身变更为另一个节点的根节点,就可以实现两个树的合并,即并集。
2.最优灌溉问题
本质都一样,求最小生成树
3.代码实现

# include <iostream>
# include <algorithm>
using namespace std;
struct vex  //水渠结构体数组
{
    int i,j,a;
};
int node[100];   //并查集的节点数组,值代表当前节点的父节点
bool comp(vex a,vex b) //自定义比较函数
{
    return a.a<b.a;
}
int find( int a) //并查集的查询算法
{
    return node[a] == a ? a : find(node[a]);
}
int main()
{
    int m,n;//m代表麦田数量   n代表可建立的水渠数量
    scanf("%d %d",&m,&n);
    vex v[100];
    for(int i =0;i<n;i++)
    {
        scanf("%d %d %d",&v[i].i,&v[i].j,&v[i].a); //输入每一条可建造的水渠的数据
    }
    for(int i=0;i<m;i++)
    {
        node[i] = i;  //初始化每个麦田所在树结构的根节点为自身
    }
    sort(v,v+m,comp);//先根据每条水渠的花费对水渠结构体数组进行排序 从小到大
    int num = 0;//  记录最终花费
    int bian = 0; //记录当前建造的水渠数量
    for(int i = 0;bian < m-1;i++) 
    {
        if(find(v[i].i) != find(v[i].j)) //如果父节点不相同,说明该两个麦田不在一个树中,则把该两个节点合并到一个树中,即使父节点相同,
        {                                                                       //建造这两个麦田之间的水渠,因为已经过排序,所以是当前花费最少的一个水渠   
            num+=v[i].a; //增加花费                                    如果两个麦田的根节点相同,说明这两个麦田以通水田,不需要再建立,则跳过该条水渠的建立
            bian++; //增加水渠数量
            node[v[i].j] = find(v[i].i); //使v[j].j节点的根节点 = v[i].i节点的根节点
            printf("%d --- %d     %d\n",v[i].i,v[i].j,v[i].a);  //打印出当前建造的水渠的起始于结束节点与花费
        }
    }
    printf("最少花费:   %d",num);
    return 0;
}

这里面用到了sort函数,是algorithm库里自带的一个排序函数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值