最小二叉树

       最小二叉树常常用在找最短路径、最小花费等题目中。与之相关的算法有两种,Prim算法和Kruskal算法,比较常用的是Kruskal算法,而且Prim算法没怎么理解清楚,所以就写记一下Kruskal算法吧。

      

实现步骤(T表示边的集合)

       1.T的初试状态是空集

       2.T中的边数小于n-1条时:

           a.E(G)中选择权值最小的边(u,v)并删除

           b.(u,v)不和T中的边一起构成回路,则将边(u,v)加入T

典型的题目比较多,这里就以poj1258为例:

    题目大意:Tom有n个农场,他要修建公路,是每个农场连接起来(直接或间接),并且要使公路长度之和最小,使花费最少。

代码实现:

   

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define maxn 120
using namespace std;

typedef struct node
{
   int u, v, len;
}p;

p edge[maxn*maxn];
int vexNum, s[maxn];

bool cmp(node a, node b)
{
    if(a.len < b.len)
          return true;
    else
        return false;
}

void build()
{
    for(int i = 1; i<=vexNum; i++)
        s[i] = i;
}

int Find(int k)
{
    if(k == s[k]) return k;
    else return Find(s[k]);
    return  s[k];
}

void Union(int a, int b)
{
    s[a] = b;
}

int main()
{
    int m;
    while(~scanf("%d", &vexNum)){
            build();
            int temp = 0;
            for(int i = 1; i<=vexNum; i++)
                for(int j = 1; j<=vexNum; j++){
                    scanf("%d", &m);
                    edge[temp].u = i;
                    edge[temp].v = j;
                    edge[temp].len = m;
                    temp++;
         }
         sort(edge, edge+temp, cmp);//对农场之间的距离排序
         int sum = 0, fa, fb;
         for(int i = 0; i<temp; i++){
            fa = Find(edge[i].u);
            fb = Find(edge[i].v);
            if(fa == fb) continue;//同一个点,或形成回路时继续循环
            sum += edge[i].len;
            Union(fa, fb);//对已经选取的点进行标记,当出现回路时,就会有有fa=fb
         }
         printf("%d\n", sum);
    }
    return 0;
}
相关题目: hdu1683hdu1232hdu1875

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值