图论中的树

这篇具有很好参考价值的文章主要介绍了图论中的树。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

树的性质与遍历

树者,千载之长存也。

树的性质与遍历树的性质:树的遍历:

树的性质:

  • 无向连通性

树是一个无向连通图,也就是说,任意两个节点之间存在唯一的路径。

  • 无回路

树不包含任何回路或环,也就是说,不存在任何节点能够经过若干条边回到自身。

  • N-1条边

一个树由 N 个节点组成,其中有 N-1 条边连接这些节点。

  • 唯一路径

在树中,任意两个节点之间存在唯一的路径,也就是说,从树的根节点出发,可以通过唯一的路径到达任意一个节点。

  • 无向无权图

树是一种无向无权图,即每条边没有权重或距离的概念。

  • 最小连通子图

对于给定的连通图,如果删除任意一条边,都会使得图不再连通,那么这个连通图就是一棵树。换句话说,树是最小连通子图。

树的遍历:

  • 深度优先遍历

搜索路径、连通性等问题

板子

using namespace std;
const int N = 1e5 + 7;
vector<int> v[N];
bool use[N];
int n, d,ans = 0;
void dfs(int pos, int val) {
    if (val == d) return;
    
    use[pos] = 1;
    
    for (int i = 0; i < v[pos].size(); i++) 
        if (use[v[pos][i]] == 0) {
            use[v[pos][i]] = 1;
            dfs(v[pos][i], val + 1);
            ans++;
        }
    
}
​
int main() {
    cin >> n>>d;
    int begin, to;
    
    for (int i = 1; i <= n-1; i++) {
        cin >> begin >> to;
        v[begin].push_back(to);
        v[to].push_back(begin);
    }
    
    dfs(1, 0);
    cout << ans;
}
  • 广度优先遍历

寻找最短路径、层级分析等问题

板子(注意,只是普通广搜,若要涉及最短路,则在后面章节)

using namespace std;
const int N = 1e5 + 7;
vector<int> v[N];
bool use[N];
int n, d;
int main() {
    cin >> n>>d;
    int begin, to;
    
    for (int i = 1; i <= n-1; i++) {
        
        cin >> begin >> to;
        v[begin].push_back(to);
        v[to].push_back(begin);
        
    }
    
    queue<int> q;
    q.push(1);
    use[1] = 1;
​
    while (!q.empty()) {
​
        int now = q.front();
        q.pop();
​
        for (int i = 0; i < v[now].size(); i++) {
            if (use[v[now][i]] == 0) {
                q.push(v[now][i]);
            }
            use[v[now][i]] = 1;
        }
​
    }
}

注意事项:

  1. 注意题给信息决定是否要建立反向边

  2. 对于无向图,要注意开标记数组


树的直径与重心

“万木悉自寒,孤松独秀时。重心在地底,直径正天涯。”——白居易

树的直径与重心树的直径:定义求法注意树的重心定义性质求法换根DP求重心代码:

树的直径:

定义

树的直径是指树中最长路径的长度。也可以理解为在树中任选两个节点,它们之间的最长路径的长度即为树的直径。

求法

首先从任意节点开始进行一次深度优先搜索,找到距离该节点最远的节点A。然后从节点A开始进行第二次深度优先搜索,找到最远的节点B,那么节点A和节点B之间的路径长度就是树的直径。

注意

一棵给定的树中,直径的长度是一定的,但直径的路径是不一定的

树的重心

定义

将树中的某一结点删除,这棵树将散架,分成若干棵子树,设其中最大的一棵树结点数量为 N。以此类推,遍历每一个结点,找到最小的N,此时删除的结点就是重心

性质

  • 树的重心如果不唯一,则至多有两个,且这两个重心相邻。

  • 以树的重心为根时,所有子树的大小都不超过整棵树大小的一半。

  • 树中所有点到某个点的距离和中,到重心的距离和是最小的;如果有两个重心,那么到它们的距离和一样。

  • 把两棵树通过一条边相连得到一棵新的树,那么新的树的重心在连接原来两棵树的重心的路径上。

  • 在一棵树上添加或删除一个叶子,那么它的重心最多只移动一条边的距离。

求法

比较常见的求法是换根dp

这种求法不是通过重心的定义来求解,而是通过重心的一个性质,

也就是树中所有的点到重心的距离之和最小

怎么实现的?

我们假设

n为所有结点的个数

Sum_distance[i]表示树上所有的点到i的的距离之和。

Size[i]表示以i根的子树的大小。

对树上的任意一个非根结点x,设其父结点为y,有转移方程Sum_distance[x]=Sum_distance[y] + (n-Size[x]) - Size[x]

解释一下:

我们的状态转移是从根节点开始,慢慢向下转移。

所以对于x的父结点y ,其状态已经被计算过了。

我们现在要往下移动一个单位到其儿子x,那么对于x的子树部分的任意一个结点,其到 x的距离就等于其到 y的距离-1,总共减少的距离是Size[x]

对于非x的子树部分的任意一个结点,其到x的距离就等于其到y的距离+1,总共增加的距离是n-Size[x]

那么,很显然,需要改变的距离是能计算出来的。

也就是(n-Size[x]) - Size[x]

化简后的式子就是:Sum_distance[x]=Sum_distance[y] + n - 2*Size[x]

换根DP求重心代码:

1、先求出每个结点子树大小

void get_size(int now,int fa) { // fa指的是当前这个点的父结点
​
​
    Size[now] = 1;//now结点的子树大小初始化为1
​
    for (int i = 0; i < v[now].size(); i++) {
        if (v[now][i] != fa) { //不能回头搜索
            get_size(v[now][i], now);
            Size[now] += Size[v[now][i]]; 
        }
    }
    
    
}

2、求出树中所有的点到根节点的距离之和

ps:即求每个点的深度之和

int get_d1(int now,int fa,int depth) {
    int ans = 0;
​
    for (int i = 0; i < v[now].size(); i++) 
        if (v[now][i] != fa)        
            ans+=get_d1(v[now][i],now,depth+1)+depth;
    
    return ans;
}

3、换根DP过程

ps:use[i]是标记数组,用来记录这个点是否被搜过文章来源地址https://www.toymoban.com/news/detail-815757.html

void get_alld(int now, int fa) {
    use[now] = 1;
    
    for (int i = 0; i < v[now].size(); i++) {
        if (son != fa and use[son] == 0) {
            d[v[now][i]] = d[now] + Size[1] - 2 * Size[v[now][i]];
            get_alld(v[now][i], fa);
        }   
    }
    
}

到了这里,关于图论中的树的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 图论中的GLM模型

    在一般统计中,常用的coding方式有dummy,effect和cell.mean,这个在R和python中都可以实现。 dummy coding 举例 假设有4个组别A, B, C, D,它的自由度是4-1=3,因此它可以用3个不同位置的1来编码代表4个组(有一个组作为reference组,其编码全为0). 假设如下的表格数据: 把g4组作为参考组

    2024年01月21日
    浏览(42)
  • 图论与算法(3)图的深度优先遍历

    图的遍历 是指按照一定规则访问图中的所有顶点,以便获取图的信息或执行特定操作。常见的图遍历算法包括深度优先搜索(DFS)和广度优先搜索(BFS)。 深度优先搜索 (DFS):从起始顶点开始,递归或使用栈的方式访问相邻的顶点,直到所有顶点都被访问过为止。DFS通过

    2024年02月06日
    浏览(41)
  • 线性代数在图论中的应用

    图论是一门研究有限数量的点(节点)和它们之间的关系(边)的学科。图论在计算机科学、数学、物理、生物学和社会科学等领域具有广泛的应用。线性代数则是一门研究向量和矩阵的学科,它在许多领域中都有着重要的应用,包括物理学、生物学、经济学和人工智能等。

    2024年02月03日
    浏览(34)
  • 矩阵范数与图论: 在图论中的应用和理论基础

    矩阵范数和图论是计算机科学和数学领域中的两个重要概念。矩阵范数是一种用于衡量矩阵“大小”的度量,而图论则是用于描述和分析网络结构的工具。在本文中,我们将探讨这两个领域之间的联系,并讨论它们在实际应用中的重要性。 矩阵范数的概念可以追溯到19世纪的

    2024年04月10日
    浏览(29)
  • 图论中的聚类系数(Clustering coefficient)简单介绍

    在GraphSage论文的理论分析部分,涉及到一个概念叫做“ Clustering coefficient” ,直译过来就是 聚类系数 ,解释为“节点的一跳邻域内封闭的三角形的比例”,本文对其做一个简单的介绍。本文参考了 Wiki百科-Clustering coefficient。 更:关于GraphSage论文详解,请参见博文《GraphSag

    2023年04月09日
    浏览(20)
  • 图论算法|深度优先搜索理论基础|797.所有可能的路径|广度优先搜索BFS理论基础|200. 岛屿数量

    dfs是可一个方向去搜,不到黄河不回头,直到遇到绝境了,搜不下去了,在换方向(换方向的过程就涉及到了回溯)。 递归和回溯是相辅相成的 https://leetcode.cn/problems/all-paths-from-source-to-target/ 有向无环图(DAG): 有环无向图是指在图中存在至少一个环(Cycle)的无向图。环是

    2024年02月15日
    浏览(46)
  • 【算法导论】图论(图的基本概念,图上的深度优先搜索(DFS),广度优先搜索(BFS),最小生成树(MST)及Prim,Kruskal算法)

    图(Graph)是一种包含节点与节点的边的集合,记作G=(V,E),V是节点的集合,E是边的集合。 有向图 一个有向图G=(V,E),E中每个元素是V上的一个二值关系:一条从a出发的连向b的边e可以记作一个 有序 对e = (a,b) 。 无向图 一个无向图G=(V,E),E的每个元素e可以表示V上的一个 无序 对,记

    2024年02月03日
    浏览(33)
  • 【深度优先搜索】【图论】【树】2646. 最小化旅行的价格总和

    【数位dp】【动态规划】【状态压缩】【推荐】1012. 至少有 1 位重复的数字 深度优先搜索 图论 树 现有一棵无向、无根的树,树中有 n 个节点,按从 0 到 n - 1 编号。给你一个整数 n 和一个长度为 n - 1 的二维整数数组 edges ,其中 edges[i] = [ai, bi] 表示树中节点 ai 和 bi 之间存在

    2024年02月19日
    浏览(28)
  • 每天一道leetcode:797. 所有可能的路径(图论&中等&深度优先遍历)

    给你一个有 n 个节点的 有向无环图(DAG) ,请你找出所有从节点 0 到节点 n-1 的路径并输出( 不要求按特定顺序 ) graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j] 存在一条有向边)。 n == graph.length 2 = n = 15 0 = graph[i][j] n graph[i][j] != i (即不存

    2024年02月12日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包