边分治用来解决一些点分治中一些解决不了的问题。
比如说点分治时有很多棵子树,合并这些信息时不能保证时间复杂度。
而边分治时最多只会有两棵子树,就可以很好地解决问题。
算法与点分治大致相同,就是找到一条边使得删去这条边后最大的那棵子树的大小最小。
但这个算法在菊花图时时间复杂度会退化成$O(n^2)$,因此需要将原树转换为一棵二叉树,这样每个点度数最多为$3$,分治后子树大小最多为原树的$\frac{2}{3}$,就不会出现刚刚那样的问题了。
但边分治还有一个限制条件,那就是后来加进去的边对答案不会产生影响
我的多叉树转二叉树的代码,(显然最后的点数nn
最多只有$2n$):
1 | void dfs1(int u, int father) |
当然可以更简单粗暴一些,代价就是点数会稍微多一点点,但还是不会超过$2n$:
1 | int main() |
其他的部分和点分治差不多。
这里是找根的代码:
1 | void getroot(int u, int father, int S) |
分治的大致框架:
1 | void dfs(int u, int father, int cas, ) |