bzoj3302】的更多相关文章

BZOJ3302: [Shoi2005]树的双中心 https://lydsy.com/JudgeOnline/problem.php?id=3302 分析: 朴素算法 : 枚举边,然后在两个连通块内部找到带权重心计算答案. 然后我们发现在内部找重心是方向唯一,因此可以预处理出来这个点向下走的最优儿子和次优儿子. 然后每次从上往下找重心即可. 时间复杂度\(O(n\times dep)\). 代码: #include <cstdio> #include <cstring> #inc…
[BZOJ3302][Shoi2005]树的双中心 Description Input 第一行为N,1<N<=50000,表示树的节点数目,树的节点从1到N编号.接下来N-1行,每行两个整数U,V,表示U与V之间有一条边.再接下N行,每行一个正整数,其中第i行的正整数表示编号为i的节点权值为W(I),树的深度<=100 Output 将最小的S(x,y)输出,结果保证不超过19^9 Sample Input 5 1 2 1 3 3 4 3 5 5 7 6 5 4 Sample Outpu…
三倍的幸福! 暴力的做法就是枚举每一条边断开,选的两个点就是左右两棵树的重心. 可以发现找重心的时候一定是往权和大的子树找的,需要维护一个点的最大和次大子树,因为最大子树可能被割掉了,实际效率为O(NH). 设sum[i]为子树i的权和,core[i]为i的子树中i作为重心的答案. 断掉一条边(x,y)的时候两棵树一棵包含根,一棵包含y,则一棵的答案为core[root]-core[y]-sum[y]*dep[y],一棵为core[y],找重心到x时更新答案now=now+sum[root]-2…
树形dp 很明显我们可以枚举一条边,然后求两边的重心,这样是暴力,我们用一些奇怪的方法来优化这个找重心的过程,我们先预处理出来每个点最大和第二的儿子,然后每次把断掉的子树的贡献减掉,每次找重心就是向最大或第二大的儿子走,如果最大的儿子被减掉后比第二大的儿子小或者这条边被剪掉了,那么就向第二大的儿子走,这样复杂度是h的 #include<bits/stdc++.h> using namespace std; typedef long long ll; ; int n; ll ans = 1e18…