传送门

强行安利->巨佬题解

如果只有一个点贡献答案,那么答案显然是这棵树的带权重心,这个是可以\(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]树的双中心的更多相关文章

  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. 题解-SHOI2005 树的双中心

    SHOI2005 树的双中心 给树 \(T=(V,E)(|V|=n)\),树高为 \(h\),\(w_u(u\in V)\).求 \(x\in V,y\in V:\left(\sum_{u\in V} ...

  4. 【BZOJ】3302: [Shoi2005]树的双中心 && 2103: Fire 消防站 && 2447: 消防站

    [题意]给定带点权树,要求选择两个点x,y,满足所有点到这两个点中较近者的距离*点权的和最小.n<=50000,h<=100. [算法]树的重心 [题解]代码参考自:cgh_Andy 观察 ...

  5. 【洛谷 P2726】 [SHOI2005]树的双中心(树的重心)

    先考虑一个\(O(N^2)\)做法. 设选的两个点为\(x,y\),则一定可以将树分成两个集合\(A,B\),使得\(A\)集合所有点都去\(x\),\(B\)集合所有点都去\(y\),而这两个集合的 ...

  6. [SHOI2005]树的双中心

    题目链接:Click here Solution: 首先我们要知道,选择两个点\(A,B\),必定存在一条边,割掉这条边,两个集合分别归\(A,B\)管 再结合题目,我们就得到了一个暴力的\(n^2\ ...

  7. bzoj 3302&2447&2103 树的双中心 树形DP

    题目: 题解: bzoj 3302 == 2447 == 2103 三倍经验 首先我们考虑枚举两个中心的位置,然后统计答案. 我们发现,一定有一部分点离第一个中心更近,另一部分点离第二个中心更近 如果 ...

  8. Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树)

    Luogu 2590 [ZJOI2008]树的统计 / HYSBZ 1036 [ZJOI2008]树的统计Count (树链剖分,LCA,线段树) Description 一棵树上有n个节点,编号分别 ...

  9. [luogu P3384] [模板]树链剖分

    [luogu P3384] [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点 ...

随机推荐

  1. JavaScript——DOM树的增查改删总结

    对HTML DOM的操作是前端JavaScript编程时必备的技能,本文是我自己对DOM树操作的总结,主要是方法的罗列,原理性的讲述较少,适合大家用于理清思路或是温习 一.什么是HTML DOM? 是 ...

  2. Java OOM 常见情况

    Java OOM 常见情况 原文:https://blog.csdn.net/qq_42447950/article/details/81435080 1)什么是OOM?  OOM,全称“Out Of ...

  3. hihocoder部分题解

    hihocoder1609 数组分拆II [dp] 给定数组,问有多少种拆法,使得每一段不出现重复的数字,且要保证分组数最少.(1e5) 题解: O(n) d[i]表示1~i最小划分的段数, f[i] ...

  4. 【转载】LCT

    原标题:LCT(Link-Cut Tree)详解(蒟蒻自留地) 出处:https://blog.csdn.net/saramanda/article/details/55253627 如果你还没有接触 ...

  5. Leetcode 191.位1的个数 By Python

    编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量). 示例 : 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 00000000000 ...

  6. 51nod 1061 最复杂的数V2

    题目链接 51nod 1061 题面简述 求\([1, n]\)中约数个数最多的数. \(n \le 10^{200}\) 题解 首先,答案一定是一个反素数. 什么是反素数? 一个正整数\(x\)是反 ...

  7. 最长公共子序列LCS(POJ1458)

    转载自:https://www.cnblogs.com/huashanqingzhu/p/7423745.html 题目链接:http://poj.org/problem?id=1458 题目大意:给 ...

  8. 字符串格式化format方法

    通过位置参数传参 print('{}, {}'.format('KeithTt', 18)) # KeithTt, 18 位置参数可以通过索引调用 print('{1}, {0}'.format('K ...

  9. Python--Django学习笔记2

    本篇介绍Django中的Model层. 首先介绍sqlite3,这是在当前版本中Django默认使用的数据库,sqlite也是Android中所使用的数据库. 接着介绍最最最常见的MySQL数据库如何 ...

  10. 洛谷P4364 IIIDX

    题意:给定n个数和k,把n个数排成序列,满足ai >= ai/k,并使之字典序最大. 解:毒瘤线段树贪心... 以i/k为i的父亲构树. 当这n个数不同的时候,直接后序遍历贪心即可. 正解神奇的 ...