luogu P2726 [SHOI2005]树的双中心
强行安利->巨佬题解
如果只有一个点贡献答案,那么答案显然是这棵树的带权重心,这个是可以\(O(n)\)求的.一个\(O(n^2)\)暴力是枚举两个集合之间的分界边,然后对这两个集合分别算答案,合并更新
考虑优化此过程,一个结论是一棵树内,只有\(size_i*2>size_{root}\)的点才有可能成为带权重心,并且这一类点个数不超过2个 不会证啊qwq,感性理解一下吧.所以每次枚举是哪条边为分界线,然后把树分成两部分,从每个树的根开始算答案,如果\(size_i*2\le size_{root}\)就停止
注意要扣除下面子树对上面子树的\(size\)的贡献再做
更多细节详见代码
#include<bits/stdc++.h>
#define LL long long
#define il inline
#define re register
#define db double
#define eps (1e-5)
using namespace std;
const int N=50000+10;
il LL rd()
{
LL x=0,w=1;char ch=0;
while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
int to[N<<1],nt[N<<1],hd[N],tot=1;
il void add(int x,int y)
{
++tot,to[tot]=y,nt[tot]=hd[x],hd[x]=tot;
++tot,to[tot]=x,nt[tot]=hd[y],hd[y]=tot;
}
int n,fa[N],sz[N],de[N],g[N],fc[N],sc[N],no,ans=1<<30;
void dfs(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y==fa[x]) continue;
fa[y]=x,de[y]=de[x]+1,dfs(y),sz[x]+=sz[y],g[x]+=g[y]+sz[y];
if(sz[fc[x]]<=sz[y]) sc[x]=fc[x],fc[x]=y;
else if(sz[sc[x]]<sz[y]) sc[x]=y;
}
}
void cal(int x,int nw,int size,int &an)
{
an=min(an,nw);
int y=sz[fc[x]]<sz[sc[x]]||fc[x]==no?sc[x]:fc[x];
if(sz[y]*2>size) cal(y,nw-sz[y]+size-sz[y],size,an);
}
void work(int x)
{
for(int i=hd[x];i;i=nt[i])
{
int y=to[i];
if(y!=fa[x])
{
no=y;
for(int xx=x;xx;xx=fa[xx]) sz[xx]-=sz[y];
int aa=1<<30,bb=1<<30;
cal(1,g[1]-g[y]-de[y]*sz[y],sz[1],aa),cal(y,g[y],sz[y],bb);
for(int xx=x;xx;xx=fa[xx]) sz[xx]+=sz[y];
ans=min(ans,aa+bb);
work(y);
}
}
}
int main()
{
n=rd();
for(int i=1;i<n;i++) add(rd(),rd());
for(int i=1;i<=n;i++) sz[i]=rd();
dfs(1),work(1);
printf("%d\n",ans);
return 0;
}
luogu P2726 [SHOI2005]树的双中心的更多相关文章
- 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行,每行两个整 ...
- 题解-SHOI2005 树的双中心
SHOI2005 树的双中心 给树 \(T=(V,E)(|V|=n)\),树高为 \(h\),\(w_u(u\in V)\).求 \(x\in V,y\in V:\left(\sum_{u\in V} ...
- 【BZOJ】3302: [Shoi2005]树的双中心 && 2103: Fire 消防站 && 2447: 消防站
[题意]给定带点权树,要求选择两个点x,y,满足所有点到这两个点中较近者的距离*点权的和最小.n<=50000,h<=100. [算法]树的重心 [题解]代码参考自:cgh_Andy 观察 ...
- 【洛谷 P2726】 [SHOI2005]树的双中心(树的重心)
先考虑一个\(O(N^2)\)做法. 设选的两个点为\(x,y\),则一定可以将树分成两个集合\(A,B\),使得\(A\)集合所有点都去\(x\),\(B\)集合所有点都去\(y\),而这两个集合的 ...
- [SHOI2005]树的双中心
题目链接:Click here Solution: 首先我们要知道,选择两个点\(A,B\),必定存在一条边,割掉这条边,两个集合分别归\(A,B\)管 再结合题目,我们就得到了一个暴力的\(n^2\ ...
- bzoj 3302&2447&2103 树的双中心 树形DP
题目: 题解: bzoj 3302 == 2447 == 2103 三倍经验 首先我们考虑枚举两个中心的位置,然后统计答案. 我们发现,一定有一部分点离第一个中心更近,另一部分点离第二个中心更近 如果 ...
- Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)
Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...
- [luogu P3384] [模板]树链剖分
[luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...
随机推荐
- loadrunner基础学习笔记六-运行负载
controller视图: 场景组 窗格:查看场景组内vuser状态,使用窗格右侧的按钮可以启动.停止和重置场景,查看各个vuser的状态,通过手动添加更多vuser增加场景运行期间应用程序的负载 场 ...
- LODOP在页面不同位置输出页眉页脚
Lodop中的页眉页脚项的特点是:每页固定位置输出,具体该特点可查看本博客的其他博文:Lodop打印项对象类型属性区分 Lodop中有可以设置打印项次页偏移属性,但是该方法是针对单个打印项自动分页的, ...
- Nginx REWRITE阶段
rewrite_log on ;#每次rewrite都会记录一条记录在errorlog里 error_log logs/xxx.log notice; location /first { rewrit ...
- BZOJ3261最大异或和——主席树
题目描述 给定一个非负整数序列{a},初始长度为N. 有M个操作,有以下两种操作类型: 1.Ax:添加操作,表示在序列末尾添加一个数x,序列的长度N+1. 2.Qlrx:询问操作,你需要找到一个位置p ...
- 洛谷 P2300 合并神犇 解题报告
P2300 合并神犇 题目背景 loidc来到了NOI的赛场上,他在那里看到了好多神犇. 题目描述 神犇们现在正排成一排在刷题.每个神犇都有一个能力值p[i].loidc认为坐在附近的金牌爷能力参差不 ...
- 【转】CPU上下文切换的次数和时间(context switch)
http://iamzhongyong.iteye.com/blog/1895728 什么是CPU上下文切换? 现在linux是大多基于抢占式,CPU给每个任务一定的服务时间,当时间片轮转的时候,需要 ...
- Jenkins中配置邮件通知实例演示
前言:本文通过安装配置Jenkins实现邮件通知,告知一个C# Git Repo的build成功与否 一.预配条件 在windows上安装Jenkins和它推荐安装的Plugins 创建一个@163. ...
- Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)
Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...
- A1104. Sum of Number Segments
Given a sequence of positive numbers, a segment is defined to be a consecutive subsequence. For exam ...
- javascript - ie - css - 动态更新鼠标指针形状
最近写了一个图片展示的页面,在弹出层中显示大图,在大图的左边和右边点击时可以翻页. 将鼠标在大图上移动时,移动到左边显示一个向左的箭头,移动到右边时显示一个向右的箭头. 当第一次显示大图时,如果鼠标位 ...