树形dp

很明显我们可以枚举一条边,然后求两边的重心,这样是暴力,我们用一些奇怪的方法来优化这个找重心的过程,我们先预处理出来每个点最大和第二的儿子,然后每次把断掉的子树的贡献减掉,每次找重心就是向最大或第二大的儿子走,如果最大的儿子被减掉后比第二大的儿子小或者这条边被剪掉了,那么就向第二大的儿子走,这样复杂度是h的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e4 + ;
int n;
ll ans = 1e18;
vector<int> G[N];
int dep[N], a[N], fa[N], son[N], bro[N];
ll sum[N], size[N];
void dfs(int u, int last)
{
size[u] = a[u];
fa[u] = last;
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(v == last) continue;
dep[v] = dep[u] + ;
dfs(v, u);
size[u] += size[v];
sum[u] += sum[v] + size[v];
if(!son[u] || size[v] > size[son[u]]) bro[u] = son[u], son[u] = v;
else if(!bro[u] || size[v] > size[bro[u]]) bro[u] = v;
}
}
void center(ll &ret, int ban, ll tot, int u, ll S)
{
ret = min(ret, S);
int v = son[u];
if(v == ban || size[bro[u]] > size[v]) v = bro[u];
if(!v) return;
center(ret, ban, tot, v, S + tot - * size[v]);
}
void solve(int u, int last)
{
for(int i = ; i < G[u].size(); ++i)
{
int v = G[u][i];
if(v == last) continue;
for(int x = u; x; x = fa[x]) size[x] -= size[v];
ll tmp1 = 1e16, tmp2 = 1e16;
center(tmp1, v, size[], , sum[] - sum[v] - size[v] * dep[v]);
center(tmp2, , size[v], v, sum[v]);
ans = min(ans, tmp1 + tmp2);
for(int x = u; x; x = fa[x]) size[x] += size[v];
solve(v, u);
}
}
int main()
{
scanf("%d", &n);
for(int i = ; i < n; ++i)
{
int u, v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
for(int i = ; i <= n; ++i) scanf("%lld", &a[i]);
if(n <= )
{
puts("");
return ;
}
dfs(, );
solve(, );
printf("%lld\n", ans);
return ;
}

bzoj3302的更多相关文章

  1. BZOJ3302: [Shoi2005]树的双中心

    BZOJ3302: [Shoi2005]树的双中心 https://lydsy.com/JudgeOnline/problem.php?id=3302 分析: 朴素算法 : 枚举边,然后在两个连通块内 ...

  2. 【BZOJ3302】[Shoi2005]树的双中心 DFS

    [BZOJ3302][Shoi2005]树的双中心 Description Input 第一行为N,1<N<=50000,表示树的节点数目,树的节点从1到N编号.接下来N-1行,每行两个整 ...

  3. bzoj3302&bzoj2447&bzoj2103(树的重心)

    三倍的幸福! 暴力的做法就是枚举每一条边断开,选的两个点就是左右两棵树的重心. 可以发现找重心的时候一定是往权和大的子树找的,需要维护一个点的最大和次大子树,因为最大子树可能被割掉了,实际效率为O(N ...

随机推荐

  1. 2.JAVA语言基础部分

    1.语言基础 二进制操作 "&"按位与:a与b同时为1结果为1,否则为0: "|"按位或:a与b其中任一个为1,否则为0 "~"按位 ...

  2. Java全局变量不加修饰符时的访问权限范围

    如上图所示.

  3. JS实现根据密码长度 显示安全条

    原文:http://www.open-open.com/code/view/1431324883763 //根据密码长度显示安全条 <ul class="clear"> ...

  4. iinflux数据库使用

    特殊用法: http://blog.fatedier.com/2016/07/05/research-of-time-series-database-influxdb/ 创建表及表中的key和valu ...

  5. HDU 1257 最少拦截系统(dp)

    Problem Description 某国为了防御敌国的导弹突击,发展出一种导弹拦截系统.可是这样的导弹拦截系统有一个缺陷:尽管它的第一发炮弹可以到达随意的高度,可是以后每一发炮弹都不能超过前一发的 ...

  6. [网页游戏开发]Morn组件赋值

    在讲解List之前,我们先介绍一下Morn组件赋值功能 默认属性赋值 界面逻辑开发过程中,经常会涉及到动态更改UI属性,比如: 界面有一个按钮,一个多选框和一个文本,分别命名为myButton,myC ...

  7. Testng 运行报错:"Total tests run: 0, Failures: 0, Skips: 0"以及找不到class文件的问题

    "Total tests run: 0, Failures: 0, Skips: 0" This means that there were no tests executed a ...

  8. WPF代码注意事项,开发常见问题,知识总结

    代码注意事项: 1.代码实现的样式赋值 XXX.Style = TryFindResource("StyleName") as Style; 2.WPF中FindName方法的使用 ...

  9. Entity Framework 6 Code First系列1: 实体类1:1配置

    从4.1版本开始,EF开始支持Code First模式,值得注意的是Code First不是和DataBase First或Model First平级的概念,而是和EDM平级的概念.使用Code Fi ...

  10. intellij IDEA 更新java后不用重启tomcat

    最近项目大了,每次修改后重启都要等和很久,那个煎熬…… 为了解决这个问题,万能的Google  装了这个  JREBEL 5.63最新的 安装步骤: 一.IDEA在线搜索 jrebel  安装 二.破 ...