精华内容
下载资源
问答
  • n节点,n-1条边。

    n个节点,n-1条边。

    展开全文
  • 分钟搞明白生成树和最小生成树的定义

    万次阅读 多人点赞 2017-11-15 07:57:53
    注意文字意思:不管是生成树还是最小生成树一定还是输,千万别和图混淆了。下面来说生成树:我们这棵树是针对图来说的,... 那么我们的生成树怎么在图的基础上生成的呢? 我们学了图应该知道2种遍历方法:1深度优先

    注意文字意思:不管是生成树还是最小生成树一定还是输,千万别和图混淆了。

    下面来说生成树:我们这棵树是针对图来说的,如果你们已经知道极小连通子图就非常简单了,
    极小连通子图什么意思呢,就是我们把图中的全部节点连接起来,假如n个节点那么,边是n - 1条。

    注意形成的一定是一棵树才是生成树。

    好了回到正题:
    那么我们的生成树怎么在图的基础上生成的呢?
    我们学了图应该知道有2种遍历方法:1深度优先遍历 2广度优先遍历
    深度优先遍历(DFS)是什么意思呢:假定一个起点比如下图所示:
    这里写图片描述

    假如我知道0的地址,我们使用深度优先遍历算法遍历当前的图:
    分析:深度字面意思一定要搞定这个意思就是说我们根据当前节点访问当前节点的一个孩子,然后在访问孩子节点的一个孩子节点,一直递归下去。直到全部节点访问完毕就停止访问,否则我们就退到上个节点从另一个孩子节点开始使用相同方式访问孩子节点。
    这里写图片描述

    分析:由深度优先遍历算法得到的生成树如上图;

    我们从起点0开始,找到0的第一个邻节点2, 因此0->2->3->4->1->5.
    这个序列是确定的吗,在这个图是确定的,先0我们在找邻节点我们假如在逆时针方位开始0开始找到第一个邻节点也就是2并且都标为访问过然后就找到2的邻节点3 在就是4在就是1,这个时候是不是有4个方位,但是只有5没有访问因此就是5 这个时候全部访问完毕。

    第二个办法就是广度优先算法生成树:

    这里写图片描述

    分析:我们来看看这个生成树是怎么形成的, 我们还是0开始,标志为被访问,
    然后由于是广度优先访问全部的邻节点在访问孩子的全部邻节点 0->2 1 5 3 4

    现在引入我们的最小生成树的定义:既然是最小在是生成树的基础上,在加上假如是带权值,那么生成树的很多种当中必有一个生成树权值和是最小,那么最小那棵树就是最小生成树。

    那么权值是什么意思,比如0节点和2节点之间我们可以看成是一个城市到一个城市的车费或者路程。
    那么最小就是走遍全部城市的车费或者路程最小。

    展开全文
  • 个有 n 结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 结点,并且保持图连通的最少的边。最小生成树(Minimum Spanning Tree,MST)可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法...


    介绍

    一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树(Minimum Spanning Tree,MST)可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。

    关于图的几个概念定义:

    • 连通图:在无向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该无向图为连通图。
    • 强连通图:在有向图中,若任意两个顶点vivi与vjvj都有路径相通,则称该有向图为强连通图。
    • 连通网:在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权;权代表着连接连个顶点的代价,称这种连通图叫做连通网。
    • 生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但只有足以构成一棵树的n-1条边。一颗有n个顶点的生成树有且仅有n-1条边,如果生成树中再添加一条边,则必定成环。
    • 最小生成树:在连通网的所有生成树中,所有边的代价和最小的生成树,称为最小生成树。

    在这里插入图片描述

    Prim算法简述

    此算法可以称为“加边法”,初始最小生成树边数为0,每迭代一次就选择一条满足条件的最小代价边,加入到最小生成树的边集合里。

    1. 把图中的所有边按代价从小到大排序;
    2. 把图中的n个顶点看成独立的n棵树组成的森林;
    3. 按权值从小到大选择边,所选的边连接的两个顶点(ui,vi),(ui,vi) 应属于两颗不同的树,则成为最小生成树的一条边,并将这两颗树合并作为一颗树。
    4. 重复(3),直到所有顶点都在一颗树内或者有n-1条边为止。

    在这里插入图片描述

    Kruskal算法简述

    此算法可以称为“加点法”,每次迭代选择代价最小的边对应的点,加入到最小生成树中。算法从某一个顶点s开始,逐渐长大覆盖整个连通网的所有顶点。

    1. 图的所有顶点集合为VV;初始令集合u={s},v=V−uu={s},v=V−u;
    2. 在两个集合u,vu,v能够组成的边中,选择一条代价最小的边(u0,v0)(u0,v0),加入到最小生成树中,并把v0v0并入到集合u中。
    3. 重复上述步骤,直到最小生成树有n-1条边或者n个顶点为止。

    由于不断向集合u中加点,所以最小代价边必须同步更新;需要建立一个辅助数组closedge,用来维护集合v中每个顶点与集合u中最小代价边信息:

    struct
    {
      char vertexData   //表示u中顶点信息
      UINT lowestcost   //最小代价
    }closedge[vexCounts]
    

    在这里插入图片描述

    应用

    生成树和最小生成树有许多重要的应用。

    例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低。这就需要找到带权的最小生成树。

    知识点习题:

    1. (a, b, c) 表示 ab 两点之间距离为c,求树(a, c, 3),(b, d, 1),(b, f, 5),(d, c, 6),(d, f, 5),(e, f, 2),(a, b, 12),(a, e, 13) prim最小生成树边和为( )

    A. 19
    B. 17
    C. 18
    D. 20

    正确答案: B

    答案解析:

    a ~ c ~ d ~ b ~ f ~ e : 3 + 6 + 1 + 5 + 2 = 17

    展开全文
  • 先求一个最小生成树, 然后枚举这个最小生成树的每一条边, 然后计算分别删去这个边的图的最小生成树, 一共n - 1个, 次小生成树一定是这几个. poj1679的问图的最小生成树是否为一, 可以先求最小生成树, 在求次小生....

    kruskal算法相当简单直观~还比prim好用~

    应用一, 求最大权值最小的最小生成树.

    仔细想一想, 最小生成树的最大权值就是最小的.

    应用二, 求次小生成树.

    先求一个最小生成树, 然后枚举这个最小生成树的每一条边, 然后计算分别删去这个边的图的最小生成树, 一共有n - 1个, 次小生成树一定是这几个.

    poj1679的问图的最小生成树是否为一, 可以先求最小生成树, 在求次小生成树, 如果两个生成树的权值相等, 则说明最小生成树不唯一.

    求次小生成树的优化:

    引入概念:

    若 T 是图 G 的一个生成树, 对于非树边 a 和树边 b , 插入边 a 并删除边 b 的操作记为(+a, -b).

    如果 T + a - b 仍然是一个生成树, 称(+a, -b)是 T 的一个可行交换.

    设T为图G的一个生成树, 由T进行一个可行交换得到的新的生成树集合称为T的邻集.

    定理: 次小生成树一定在最小生成树的邻集中.

    优化方法:

    1. 通过O(n^2)求出MAX[i][j]数组, 代表着i到j之间的路径上的最大边权.

    2. 通过倍增思想, 在O(elge)的时间内求出MAX[i][j], 代表着i到i的2^j辈祖先路径的最大边权.再通过LCA可以求出任意两个节点路径之间的最大边权了.

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const int MAXN = 120;
    const int MAXM = 5500;
    int faz[MAXN];
    int n, m;
    struct Edge{
        int from, to, weight;
        Edge(int from, int to, int weight): from(from), to(to), weight(weight){}
        bool operator<(const Edge & rhs) const{
            return weight < rhs.weight;
        }
    };
    int find(int x){
        if(x == faz[x]){
            return x;
        }
        return faz[x] = find(faz[x]);
    }
    void merge(int x, int y){
        x = find(x);
        y = find(y);
        faz[x] = y;
    }
    void init(){
        for(int i = 0; i < MAXN; ++i){
            faz[i] = i;
        }
    }
    int main(){
        int T;
        scanf("%d", &T);
        while(T--){
            scanf("%d%d", &n, &m);
            int x, y, w;
            vector<Edge> v;
            for(int i = 0; i < m; ++i){
                scanf("%d%d%d", &x, &y, &w);
                v.push_back(Edge(x, y, w));
            }
            sort(v.begin(), v.end());
            init();
            vector<int> flag;
            int mst_cost = 0;
            for(int i = 0; i < v.size(); ++i){
                int x = v[i].from, y = v[i].to;
                if(find(x) != find(y)){
                    merge(x, y);
                    mst_cost += v[i].weight;
                    flag.push_back(i);
                }
            }
            int second_cost = 0x3f3f3f3f;
            for(int i = 0; i < flag.size(); ++i){
                int cur_cost = 0;
                init();
                for(int j = 0; j < v.size(); ++j){
                    if(flag[i] != j){
                        int x = v[j].from, y = v[j].to, w = v[j].weight;
                        if(find(x) != find(y)){
                            merge(x, y);
                            cur_cost += w;
                        }
                    }
                }
                int chief = find(1);
                for(int i = 2; i <= n; ++i){
                    if(find(i) != chief){
                        cur_cost = 0x3f3f3f3f;
                    }
                }
                second_cost = min(second_cost, cur_cost);
            }
            if(mst_cost == second_cost){
                printf("Not Unique!\n");
            }
            else{
                printf("%d\n", mst_cost);
            }
        }
        return 0;
    }

    应用三, 求最大权值和最小权值的差最小的生成树.

    先求最小生成树, 然后把这个生成树中的最小边从图中删除, 在求一次最小生成树, 再把这个生成树的最小边从图中删除...重复这个过程, 删去的边不能恢复.

    这其中一定有一颗最大权值和最小权值的差最小的生成树, 这很像尺取, 反过来求最大生成树也应该可以.

    注意这里算法的终止条件: 当剩余的边不足以使点联通了.

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <cstdlib>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    const int MAXN = 120;
    const int MAXM = 5500;
    int faz[MAXN];
    struct Edge{
        int from, to, limit;
        Edge(int from, int to, int limit): from(from), to(to), limit(limit){}
        bool operator<(const Edge & rhs) const{
            return limit < rhs.limit;
        }
    };
    int find(int x){
        int root = x;
        while(root != faz[root]){
            root = faz[root];
        }
        int temp;
        while(x != root){
            temp = faz[x];
            faz[x] = root;
            x = temp;
        }
        return root;
    }
    void merge(int x, int y){
        x = find(x);
        y = find(y);
        faz[x] = y;
    }
    void init(){
        for(int i = 0; i < MAXN; ++i){
            faz[i] = i;
        }
    }
    int main(){
        int n, m;
        int x, y, l;
        scanf("%d%d", &n, &m);
        int rst = 0x3f3f3f3f;
        vector<Edge> v;
        for(int i = 0; i < m; ++i){
            scanf("%d%d%d", &x, &y, &l);
            v.push_back(Edge(x, y, l));
        }
        sort(v.begin(), v.end());
        int maxn = -0x3f3f3f3f, minn = 0x3f3f3f3f;
        vector<int> smallest;
        int counter = 0;
        init();
        bool trigger = true;
        for(int i = 0; i < v.size(); ++i){
            int x = v[i].from, y = v[i].to, l = v[i].limit;
            if(find(x) != find(y)){
                merge(x, y);
                ++counter;
                maxn = max(maxn, l);
                minn = min(minn, l);
                if(trigger){
                	smallest.push_back(i);
                    trigger = false;
                }
            }
        }
        if(counter != n - 1){
            printf("-1\n");
            return 0;
        }
        rst = min(rst, maxn - minn);
        while(true){// 枚举最小边
            init();
            int counter = 0;
            maxn = -0x3f3f3f3f, minn = 0x3f3f3f3f;
            trigger = true;
            for(int i = 0; i < v.size(); ++i){
                if(lower_bound(smallest.begin(), smallest.end(), i) != smallest.end()){
                    continue;
                }
                int x = v[i].from, y = v[i].to, l = v[i].limit;
                if(find(x) != find(y)){
                    merge(x, y);
                    ++counter;
                    maxn = max(maxn, l);
                    minn = min(minn, l);
                    if(trigger){
                        smallest.push_back(i);
                        trigger = false;
                    }
                }
            }
            if(counter == n - 1){
                rst = min(rst, maxn - minn);
            }
            else{
                break;
            }
        }
        printf("%d\n", rst);
        return 0;
    }

     

    展开全文
  • 答案中每个树的结点都必须 node.val=0。 你可以按任何顺序返回树的最终列表。 输入:7 输出:[[0,0,0,null,null,0,0,null,null,0,0],[0,0,0,null,null,0,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,null,null,nu
  • 好妙的一题啊,自己是不太能想出来的,其中有几个点。第一个是,区间查询,那应该想到线段树,线段树的每个区间里面存这个区间的边能构成的最小生成树,当然不一定是一颗完整联通的树。然后就是区间合并的问题了,...
  • 最小生成树的两种方法(Kruskal算法和Prim算法)

    万次阅读 多人点赞 2018-08-17 18:20:07
    关于图的几个概念定义: 连通图:在无向图中,若任意两个顶点vivi与vjvj都路径相通,则称该无向图为连通图。 强连通图:在向图中,若任意两个顶点... 生成树:一个连通图的生成树是指一个连通子图,它含有图中...
  • 最小生成树

    2020-03-28 15:25:48
    每当我们对一个新的知识点进行学习的时候,我们总要解决以下几个问题。 最小生成树是要干什么?最小生成树能解决哪一类问题?最小生成树的原理?最小生成树的代码实现? 1,最小生成树是要干什么? 简单来说就是,...
  • 最小生成树的算法

    2018-06-09 22:52:48
    关于图的几个概念定义:连通图:在无向图中,若任意两个顶点vivi与vjvj都路径相通,则称该无向图为连通图。强连通图:在向图中,若...生成树:一个连通图的生成树是指一个连通子图,它含有图中全部n个顶点,但...
  • 头部闲扯 今天闲来在google搜了一下...想来这博客闲置一年多了,突然就想再拾起来看看,能不能再偶尔写篇,不一定为了分享给谁看,也是为了给自己整理一下思路。 正文 刚到新加坡,前两天介绍了一下 commu...
  • 浏览器解析HTML文档生成DOM树的过程,以下是一段HTML代码,以此为例来分析解析HTML文档的原理HelloWorldpicture: A paragraph of explanatory text...豌豆资源搜索网站 https://55wd.com浏览器解析HTML文档,在中发现...
  • 组织的生成

    2012-09-25 11:58:34
    先说说这个权限生成的几个需求。  数据源是从数据库读出来。数据结构是这样个treePath,里面数据是这样。  通过“/”表明数据组织层次结构,也就是说如果没有“/”就表明是根节点,如果一...
  • 这样问题是不是就迎刃而解了,我们只需要用一个变量cur存储当前图中有几个树,每次合并树的时候cur减1,当cur的值等于k的时候,合并树所需要的花费也就是最后的答案 下面附上ac代码 #include <iostream> #...
  • 天玩得比较多,就写了道最小生成树的题,都是模板题就不贴了,写下最小生成树和次最小生成树的原理,加深加深印象吧。 最小生成树 网络上也很多博客讲这,我就按我自己的想法讲。 1.普里姆算法。 这...
  • 边为向边最小生成树,用到朱-刘算法。 用以下几个步骤解决这个问题: 1, 检验图连通性 可用DFS,或者考察每个节点最短入边长度是否小于设定INF来实现 2, 将当前图每个点最短入边计入答案 3, ...
  • 最平衡生成树是这样定义的,一个有 n 结点的连通图的生成树包含原图中的所有n结点,并且最长边与最短边的差值最小。现在给你一个有n结点的图,求最平衡生成树中最长边与最短边的差值。 输入 ...
  • STP生成树

    2020-02-14 00:45:03
    1、生成树的作用:防交换机产生环路 STP的几个重要概念:根桥、DP(指定端口)、RP(根端口)、非指定端口 根桥:发出BPDU数据帧,让剩余的其他交换机计算RP、非指定端口 DP(指定端口):根桥上的端口均为指定...
  • 1、2for循环都是从2开始,因为一般我们默认开始就把第一节点加入生成树,因此之后不需要再次寻找它。 2、lowcost[i]记录是以节点i为终点最小边权值。初始化时因为默认把第一节点加入生成树,因此lowcost...
  • 最平衡生成树

    2019-09-25 08:25:25
    最平衡生成树是这样定义的,一个有 n 结点的连通图的生成树包含原图中的所有n结点,并且最长边与最短边的差值最小。现在给你一个有n结点的图,求最平衡生成树中最长边与最短边的差值。 输入 ...
  • 生成树STP

    2011-09-18 13:23:40
    生成树里面有几个名词:根桥 根端口 指定端口 根路径开销可选端口 生成树里面端口几种状态 禁用 不参与生成树选举 blocking 20s ->listening 15s->learning 15s->forwarding STP收敛需要花费30S-...
  • C.算法生成决策 1基础知识 当我们需要对一随机事件概率分布进行预测时...但把它运用于金融领域诱惑也比较大,比如说决定股票涨落因素可能有几十甚至上百种而最大熵方法恰恰能找到一同时满足成千上万种不同

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,427
精华内容 570
关键字:

树的生成树有几个