算法随笔:关于树的一些常见基本问题总结

1、判断一个图是否为树

判断步骤 有向图(转换为有根图) 无向图(转换为无根图)
找树根 计算出每个节点的入边和出边数量。树根是只有出边没有入边的点。基于有向图的树只是一个树根,如果找不到树根,或者找到了多个树根,说明这不是一棵树。 任何节点都可以当作树根。
检查父子关系 从根开始DFS遍历图,要求每个点都得被访问一次,且只能访问一次,这代表每个节点只有一个父节点。 相同
检查连通性 在DFS的过程中,检查是否所有的点都被访问到。若有节点未被访问到,说明图不连通,不是一棵树。 相同

该算法的时间复杂度为O(n+m),n为点的数量,m为边的数量。

2、距离问题

求树上点与点之间的路径长度。由于在树上两点之间只有一条路径,所以不需要用Dijkstra等复杂寻路算法。

问题 解决办法
求某个节点u到达所有其他点的距离 以u为起点,用dfs或bfs对整棵树搜索一次,复杂度为O(n)。
求所有点对之间的距离 对每个点进行一次DFS或BFS,复杂度为O(n^2)。
求两个节点之间的距离 用最近公共祖先LCA,LCA查询一次是O(logn),算上LCA前dfs预处理每个节点的深度,则是O(nlogn+logn)=O(nlogn)。

3、公共祖先和最近公共祖先LCA

4、树的直径

        树的直径指树上最远的两点间的距离,又称为树的最远点对。有两种方法求树的直径。

        1、做两次DFS(或BFS)

                (1)从树上的任意点p出发,用DFS或者BFS求距离它最远的点s。s肯定是直径的两个端点之一。

                (2)从s出发,用DFS求距离s最远的点t。t是直径的另一个端点。

                s和t就是距离最远的两个点,即树的直径的两个端点。

                由于这个算法基于贪心思想,所以不可以用于有负权边的树。当树上有负权边时,只能获得局部最优,无法获得全局最优。

        2、树形DP

5、树的重心

6、多叉树和二叉树

7、树上前缀和

        树上前缀和是指从根出发到某点的路径上的点(或者边)的权值之和。用DFS从根开始搜索到某点,逐个累加点或者边的权值即可。

8、树上差分

你可能感兴趣的:(#,算法随笔,算法,数据结构)