树+最小生成树

**

**
树:
不包含回路的连通无向图(从一个点到达另一个点,若想回去,只能原路返回),即任意两个节点间有且只有一条路径的无向图

特性:
1.一条树中的任意两个节点有且仅有唯一的一条路径连通
2.一棵树中如果有n个节点,那么它一定恰好有n-1条边
3.在一棵树中加一条边将会构成一个回路

部分定义:
根结点(祖先):没有父结点
叶结点:没有子结点
内部结点:既不是根结点,也不是叶结点
深度:从根到某个结点的层数(根为第一层)

二叉树: 每个节点最多有两个儿子(左儿子和右儿子)
(要么为空,要么由根,左,右组成)
1.满二叉树(完美二叉树): 二叉树中每个内部结点都有两个儿子,所有叶节点都有同样的深度(一颗深度为h,且有2^h -1个结点的子树)
2.完全二叉树: 通俗的说,就是满二叉树缺了一点(缺在最后一层):::严格的定义:若设二叉树的高度为h,出第h层外,其它的各层(1~h-1)的节点数都达到最大个数,第h层从右向左连续缺若干结点。(缺节点的位置是连续的,而且如果有左结点,那么一定有右结点,也就是说,要么只有左儿子,要么左右儿子都有)
3.完满二叉树:可以没有儿子,but,只要有,必须是俩

…………………
完全二叉树
1.①若一颗完全二叉树的父节点编号为k,则它的左儿子为2*k,右儿子为2*k +1
②若已知儿子(左||右)的编号为x,则父结点编号为x/2(只去商的整数部分(下取整))
③如果一个完全二叉树有n个结点,那么它的高度为log2n(以2为底)(即:最多有log2n层结点)

2.最最最典型应用——堆 • 优先队列
最小堆:父节点<子节点
最大堆:父节点>子节点

维护最大最小堆:向上调整/向下调整;
①向下调整一般用于删除堆顶元素(max||min),将新增元素直接放到堆顶这个空里
②向上调整:把新增元素放在最后,一层一层向上比较

这样相当于按层调整,时间复杂度为O(logN),时间会大大减少

完全二叉树有一个性质:最后一个非叶节点是第n/2个结点

所有子树都符合最小堆的性质,那么整颗树就是最小堆了

补充:堆排序:O(nlogn) 建立最小(大)堆,每次删除并输出顶部元素或者放入一个新的数组中,直到堆空为止,最后再输出

Kruskal

:1.并查集判断两个点是否连通
2.首先按照边的权值从小到大排序,每次从剩余的边中选择权值较小且边的两个顶点不在同一个集合内的边(就是不会产生回路的边),加入到生成树中,直到加入了n-1条边为止。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;

int n,m;
int fa[10005];

struct bian
{
    int f,t,d;
}e[10005];

int cmp(bian a,bian b)
{
    return a.d<b.d;
}

int find(int x) 
{
    if(fa[x]==x) return x;
    else return fa[x]=find(fa[x]);
//写法2:return fa[x] == x?x:fa[x] = find(fa[x]); 
}
int kru()//通过并查集 
{ 
    int ans=0;
    sort(e+1,e+m+1,cmp);
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=m;i++)
    {
        int fx=e[i].f , fy=e[i].t;
        if(find(fx)!=find(fy)) // ← 能将目前边加上的条件:不在同一个连通分量里 
        //判环:若有环,则环中的点一定一个fa,即在同一个集合中,则这条边不会加入 
        {
            fa[find(fx)]=find(fy);
            ans+=e[i].d;
        }
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    cin>>e[i].f>>e[i].t>>e[i].d;

    printf("%d\n",kru());
    return 0;
}


/*http://blog.youkuaiyun.com/loi_q/article/details/77905571*/

…………………

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值