bzoj3302
树形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的更多相关文章
- BZOJ3302: [Shoi2005]树的双中心
BZOJ3302: [Shoi2005]树的双中心 https://lydsy.com/JudgeOnline/problem.php?id=3302 分析: 朴素算法 : 枚举边,然后在两个连通块内 ...
- 【BZOJ3302】[Shoi2005]树的双中心 DFS
[BZOJ3302][Shoi2005]树的双中心 Description Input 第一行为N,1<N<=50000,表示树的节点数目,树的节点从1到N编号.接下来N-1行,每行两个整 ...
- bzoj3302&bzoj2447&bzoj2103(树的重心)
三倍的幸福! 暴力的做法就是枚举每一条边断开,选的两个点就是左右两棵树的重心. 可以发现找重心的时候一定是往权和大的子树找的,需要维护一个点的最大和次大子树,因为最大子树可能被割掉了,实际效率为O(N ...
随机推荐
- 使用SmartQQ实现的智能回复(Web QQ协议)
采用SmartQQ SDK进行开发,官网:https://github.com/ScienJus/smartqq 此项目只是集成使用的方法,在com.jsoft.robot.SmartQQUse.Re ...
- Spring的IoC容器-Spring ApplicationContext容器
Application Context是spring中较高级的容器.和BeanFactory类似,它可以加载配置文件中定义的bean,将所有的bean集中在一起,当有请求的时候分配bean. 另外,它 ...
- 关于使用uitableview 中cell 来实现uiimageview的复用和图片的异步加载
apple sample lazytableimages 1,首先设置横向显示的uitableview self.customTableview.transform = CGAffineTransfo ...
- 【lombok】使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法
错误如题:使用lombok注解,在代码编写过程中可以调用到get/set方法,但是在编译的时候无法通过,提示找不到get/set方法 报错如下: 解决方法: 1.首先查看你的lombok插件是否下载安 ...
- js时间戳和时间格式之间的转换
//时间戳转换成日期时间2014-8-8 下午11:40:20 function formatDate(ns){ return new Date(parseInt(ns) * 1000).toLoca ...
- gdb生成的core文件位置
gdb可以生成core文件,记录堆栈信息,core文件名字是下面这种格式 :core.9488,其中9488是PID 文件位置是当前目录
- 使用crontab定时执行脚本时别忘了输出重定向>
原文:https://blog.csdn.net/solmyr_biti/article/details/50683279 -------------------------------------- ...
- Android:图片中叠加文字,支持拖动改变位置
之所以做了这么一个Demo,是由于近期项目中有一个奇葩的需求:用户拍摄照片后,分享到微信的同一时候加入备注,想获取用户在微信的弹出框输入的内容.保存在自己的server上.而其实,这个内容程序是无法获 ...
- iphone 消息推送 实现
IPhone 消息推送实现 参考 资料 http://blog.csdn.net/victormokai/article/details/39501277 对生成pem 的补充 拿到mac 上生成导出 ...
- 如何快速上手一款新的嵌入式CPU芯片(记录CC2540开发经历)
新换了工作,需要熟悉新公司的产品开发项目,更新博客就懈怠了,不过环境的不同,也让我对嵌入式开发有了更深刻的理解.在原公司我主要负责在STM32F207芯片平台上, 利用UCOS+LWIP进行嵌入式服务 ...