【题目链接】 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3949

【题目大意】

  给出一棵根为1的树,每条边边长为1,请你从根连一条边到某个点,
  使得各点到根距离的总和最小,求这个最小距离和

【题解】

  假设从1连到x,那么受影响的只有1和x中点往下的部分,
  我们发现中点往下的部分根据每个点答案改变的大小可以分为多个部分,
  每个部分大小为其1-x链上的父节点子树大小减去其链上第一子节点子树大小,
  设其链上父节点为y,那么这一块里每个点的距离变化为2*dy-1-dx
  那么答案变化为∑(2*dy-1-dx)=-sizeall*dx+∑(2*dy-1)
  所以我们按链维护(1-2*dy)*sizey的前缀和,这里sizey指的是固定块的大小而不是子树大小
  固定块的大小我们可以通过子树大小加减得到,当计算另一条链的时候,我们回溯消除影响,
  对于节点x的答案,我们可以取其链上前缀和与其中点的链上前缀和的差值,
  就得到了受影响部分的(1-2*dy)*sizey的和,在加上sizeall*dx,得到答案变化
  我们求出每个节点答案可能变化的最小值,和原本的固定答案相加,就是这题的答案。

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
typedef long long LL;
const int N=200010;
vector<int> G[N];
int cnt,st[N],size[N],d[N];
LL C[N],S[N],ans,all;
void dfs(int x,int fx){
d[x]=d[fx]+1;
all+=d[x];
size[x]=1;
for(int i=0;i<G[x].size();i++){
int v=G[x][i];
if(v!=fx){
dfs(v,x);
size[x]+=size[v];
}
}
}
void dfs2(int x,int fx){
if(cnt)S[cnt]-=C[cnt]*size[x];
st[++cnt]=x;
C[cnt]=1-2*d[x];
S[cnt]=S[cnt-1]+C[cnt]*size[x];
if(fx){
int mid=(cnt+1)/2;
ans=min(ans,S[cnt]-S[mid]+1LL*size[st[mid+1]]*d[x]);
}
for(int i=0;i<G[x].size();i++){
int v=G[x][i];
if(v!=fx)dfs2(v,x);
}if(--cnt)S[cnt]+=C[cnt]*size[x];
}
int T,n;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=1;i<=n;i++)G[i].clear();
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}d[all=ans=0]=-1;
dfs(1,0);
dfs2(1,0);
printf("%lld\n",all+ans);
}return 0;
}

ZOJ 3949 Edge to the Root(树形DP)的更多相关文章

  1. ZOJ 3949 Edge to the Root( 树形dp)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3949 题解:树dp真的很直觉,或者说dp真的很直觉.就上周末比赛时其实前一 ...

  2. ZOJ 3949 Edge to the Root(想法)(倍增)

    Edge to the Root Time Limit: 1 Second      Memory Limit: 131072 KB Given a tree with n vertices, we ...

  3. ZOJ 3949 Edge to the Root

    题意: 在一棵树中,可以从根节点往其他节点加一条边,使得根节点到其他所有节点的距离和最小,输出最小的距离和. 思路: 我们考虑在加的一条边为$1 \to v$,那么在树上从$1 \to v$的路径上, ...

  4. ZOJ 3626 Treasure Hunt I(树形dp)

    Treasure Hunt I Time Limit: 2 Seconds      Memory Limit: 65536 KB Akiba is a dangerous country since ...

  5. ZOJ 3626 Treasure Hunt I (树形DP,常规)

    题意:给一棵树,一个人站在节点s,他有m天时间去获取各个节点上的权值,并且最后需要回到起点s,经过每条边需要消耗v天,问最少能收获多少权值? 思路: 常规的,注意还得跑回原地s. //#include ...

  6. ZOJ 3805 (树形DP)

    题目链接: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5337 题目大意:方块连接,呈树形.每个方块有两种接法,一种接在父块 ...

  7. ZOJ 3201 树形dp+背包(简单题)

    #include<cstdio> #include<vector> #include<cstring> #include<iostream> using ...

  8. ZOJ 3188 ZOJ 3188 Treeland Exhibition(树形DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3278 题意:给出一棵树,找出一个不大于长度为m的链,使得其他点到该链 ...

  9. 树dp...吧 ZOJ 3949

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5568 Edge to the Root Time Limit: 1 Secon ...

随机推荐

  1. Expect使用小记

    By francis_hao    May 31,2017   本文翻译了部分Expect的man手册,只选取了个人常用的功能,因此并不完善.   Expect是一个可以和交互式程序对话的程序 概述 ...

  2. Codeforces Round #531 (Div. 3) ABCDEF题解

    Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividin ...

  3. codeforces 1060 B

    https://codeforces.com/contest/1060/problem/B 题意:给你一个数C ,你要找到两个数A.B,使得A+B=C并且A的每个位的数的和最大,求最大的和是多少 题解 ...

  4. AnnotationConfigApplicationContext.的用法的核心代码

    public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationCont ...

  5. maven 压缩、合并 js, css

    转载自:http://blog.csdn.net/fangxing80/article/details/17639607 我们知道在 Web 应用开发中为了提高客户端响应速度,需要将页面使用的资源最小 ...

  6. Spring学习--切面优先级及重用切点表达式

    指定切面的优先级: 在同一个链接点上应用不止一个切面时 , 除非明确指定 , 否则它们的优先级是不确定的. 切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定. 实现 Ord ...

  7. 【Foreign】哈密顿回路 [MIM]

    哈密顿回路 Time Limit: 15 Sec  Memory Limit: 256 MB Description Input Output Sample Input 4 10 0 3 2 1 3 ...

  8. Windows autoKeras的下载与安装连接

    autoKeras autoKeras GitHub:https://github.com/jhfjhfj1/autokeras 百度网盘下载地址:http://pandownload.com/ 大牛 ...

  9. bzoj 2662&bzoj 2763 SPFA变形

    我们用dis[i,j]代表到i这个点,用j张票的最短路程,那么我们只需要在SPFA更新 的时候,用dis[i,j]更新dis[p,j]和dis[p,j+1]就行了 /***************** ...

  10. strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用。

    strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用. http://bbs.51cto.com/thread-1106891-1.html