【BZOJ3302】[Shoi2005]树的双中心 DFS
【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
1 2
1 3
3 4
3 5
5
7
6
5
4
Sample Output
HINT
选取两个中心节点为2,3
题解:这题的做法还是挺神的~
有一种暴力的方法:先枚举一条边,将这条边断开,然后两边分别求重心,但是这样做复杂度有点高。
如何优化呢?观察到树高只有300,所以我们可以从树根开始,不断向靠近重心的方向移动,不能移动时就找到了重心,复杂度是树高级别的,可以通过此题。
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=50010;
typedef long long ll;
int n,cnt;
int head[maxn],to[maxn<<1],next[maxn<<1],fa[maxn],ins[maxn];
ll siz[maxn],f[maxn][2],g[maxn];
ll tot,now,ans,sz;
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
inline ll rd()
{
ll ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void dfs1(int x)
{
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x])
{
fa[to[i]]=x,dfs1(to[i]),siz[x]+=siz[to[i]],g[x]+=g[to[i]]+siz[to[i]];
if(siz[to[i]]>siz[f[x][0]]) f[x][1]=f[x][0],f[x][0]=to[i];
else f[x][1]=(siz[f[x][1]]>siz[to[i]])?f[x][1]:to[i];
}
}
inline ll calc(int x,int y)
{
ll sy=siz[y]-(ins[y])*sz;
return now-2*sy+tot;
}
void dfs3(int x)
{
ll t1=calc(x,f[x][0]),t2=calc(x,f[x][1]);
if(t1<t2)
{
if(t1<now) now=t1,dfs3(f[x][0]);
}
else if(t2<now) now=t2,dfs3(f[x][1]);
}
void dfs2(int x,int dep)
{
ins[x]=1;
if(x!=1)
{
ll tmp=0;
tot=siz[x],sz=0,now=g[x],dfs3(x),tmp+=now;
tot=siz[1]-siz[x],sz=siz[x],now=g[1]-g[x]-dep*siz[x],dfs3(1),tmp+=now;
ans=min(ans,tmp);
}
for(int i=head[x];i!=-1;i=next[i]) if(to[i]!=fa[x]) dfs2(to[i],dep+1);
ins[x]=0;
}
int main()
{
n=rd();
int i,a,b;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
for(i=1;i<=n;i++) siz[i]=rd();
dfs1(1),ans=g[1],dfs2(1,0);
printf("%lld",ans);
return 0;
}
【BZOJ3302】[Shoi2005]树的双中心 DFS的更多相关文章
- BZOJ3302: [Shoi2005]树的双中心
BZOJ3302: [Shoi2005]树的双中心 https://lydsy.com/JudgeOnline/problem.php?id=3302 分析: 朴素算法 : 枚举边,然后在两个连通块内 ...
- 题解-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 观察 ...
- luogu P2726 [SHOI2005]树的双中心
传送门 强行安利->巨佬题解 如果只有一个点贡献答案,那么答案显然是这棵树的带权重心,这个是可以\(O(n)\)求的.一个\(O(n^2)\)暴力是枚举两个集合之间的分界边,然后对这两个集合分别 ...
- [SHOI2005]树的双中心
题目链接:Click here Solution: 首先我们要知道,选择两个点\(A,B\),必定存在一条边,割掉这条边,两个集合分别归\(A,B\)管 再结合题目,我们就得到了一个暴力的\(n^2\ ...
- 【洛谷 P2726】 [SHOI2005]树的双中心(树的重心)
先考虑一个\(O(N^2)\)做法. 设选的两个点为\(x,y\),则一定可以将树分成两个集合\(A,B\),使得\(A\)集合所有点都去\(x\),\(B\)集合所有点都去\(y\),而这两个集合的 ...
- bzoj 3302&2447&2103 树的双中心 树形DP
题目: 题解: bzoj 3302 == 2447 == 2103 三倍经验 首先我们考虑枚举两个中心的位置,然后统计答案. 我们发现,一定有一部分点离第一个中心更近,另一部分点离第二个中心更近 如果 ...
- HDU 4602 Magic Ball Game(离线处理,树状数组,dfs)
Magic Ball Game Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- Codeforces Round #200 (Div. 1) D Water Tree 树链剖分 or dfs序
Water Tree 给出一棵树,有三种操作: 1 x:把以x为子树的节点全部置为1 2 x:把x以及他的所有祖先全部置为0 3 x:询问节点x的值 分析: 昨晚看完题,马上想到直接树链剖分,在记录时 ...
随机推荐
- consist of, made up of
consist vi.由……组成:由……构成(常和介词of构成固定搭配)made up of由……组成[例如] One year consists of 365 days.一年有365天.The te ...
- Troubles in Building Android Source Code
Some Troubles or problems you may encounter while you setup the Android source code build environmen ...
- JAVA Eclipse如何重新设置工作空间workspace
窗口-首选项-常规-启动和关闭,勾选启动时提示工作空间,然后移除现有的工作空间,最好也勾选启动时刷新工作空间 重启之后就可以设置工作空间了
- Windows服务器SYSTEM权限Webshell无法添加3389账户情况突破总结
转自:http://bbs.blackbap.org/thread-2331-1-1.html 近好多Silic的朋友在Windows下SYSTEM权限的php webshell下添加账户,但是却无法 ...
- es6 webpack转es5
更新时间: 2018-7-31 首次更新. 先生成package.json npm init -y 再安装以下npm插件 npm i babel-core babel-loader babel-pre ...
- 斯坦福《机器学习》Lesson4感想--1、Logistic回归中的牛顿方法
在上一篇中提到的Logistic回归是利用最大似然概率的思想和梯度上升算法确定θ,从而确定f(θ).本篇将介绍还有一种求解最大似然概率ℓ(θ)的方法,即牛顿迭代法. 在牛顿迭代法中.如果一个函数是,求 ...
- cpu、内存、硬盘
grep -c 'model name' /proc/cpuinfo
- 谈一谈AGP
typedef enum D3DPOOL { D3DPOOL_DEFAULT = 0, D3DPOOL_MANAGED = 1, D3DPOOL_SYSTEMMEM = 2, D3DPOOL_SCRA ...
- DbVisualizer出现下列错误:Could not read XML file
数据库连接工具对于我们软件测试工程师来说是日常的工具,一旦关键时刻报些莫名的错误,相信大家很是苦恼.当然,各公司数据库连接工具各异,像DbVisualizer.PLsql.sqldeveloper.T ...
- elk systemd管理
1.logstash /etc/systemd/system/logstash.service Type=simple User=logstash Group=logstash # Load env ...