http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5568

Edge to the Root


Time Limit: 1 Second      Memory Limit: 131072 KB

Given a tree with n vertices, we want to add an edge between vertex 1 and vertex x, so that the sum of d(1, v) for all vertices v in the tree is minimized, where d(uv) is the minimum number of edges needed to pass from vertex u to vertex v. Do you know which vertex x we should choose?

Recall that a tree is an undirected connected graph with n vertices and n - 1 edges.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1 ≤ n ≤ 2 × 105), indicating the number of vertices in the tree.

Each of the following n - 1 lines contains two integers u and v (1 ≤ uv ≤ n), indicating that there is an edge between vertex u and v in the tree.

It is guaranteed that the given graph is a tree, and the sum of n over all test cases does not exceed 5 × 105. As the stack space of the online judge system is not very large, the maximum depth of the input tree is limited to about 3 × 104.

We kindly remind you that this problem contains large I/O file, so it's recommended to use a faster I/O method. For example, you can use scanf/printf instead of cin/cout in C++.

Output

For each test case, output a single integer indicating the minimum sum of d(1, v) for all vertices v in the tree (NOT the vertex x you choose).

Sample Input

2
6
1 2
2 3
3 4
3 5
3 6
3
1 2
2 3

Sample Output

8
2

Hint

For the first test case, if we choose x = 3, we will have

d(1, 1) + d(1, 2) + d(1, 3) + d(1, 4) + d(1, 5) + d(1, 6) = 0 + 1 + 1 + 2 + 2 + 2 = 8

It's easy to prove that this is the smallest sum we can achieve.


Author: WENG, Caizhi
Source: The 17th Zhejiang University Programming Contest Sponsored by TuSimple

题目大意:给你一棵树,这棵树的每条边的length都是1。然后这棵树是以1为root,定义他的weight就是所有的节点的deep和。

现在你有一个操作,对于任意的u,可以从(1,u)连接一条边,问选择哪个节点u连接可以使得树的weight最小。

思路:其实很早就有思路了...但是最近心情太烦了,写的时候都很烦,就没有做。

刚开始sb的用线段树啊,树状数组啊来维护,发现好烦。然后第二天删光了所有的代码重新来,但还是摆脱不了树状数组...(感觉就算写对了应该也是TLE了)

今天突然发现可以维护一下前缀就好了(真的是......)

首先我们可以发现,对于(1,u)连接了边以后,那么深度为deep[u]/2 + 1的这些点的deep都会发生改变。

我们从1开始进行dfs,然后我们对于经过的所有的节点,都把他定义为deep = 1.然后定义前面一个子树的区间为[l, r],当前的区间为[L, R],然后利用这个进行修改即可

具体的就是容斥一下就好了,还不懂看着代码里面的注释,然后自己画一画

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 2e5 + ;
int n;
vector<int> G[maxn];
int deep[maxn], sz[maxn];
LL cnt[maxn]; void dfs_sz(int u, int fa, int d){
deep[u] = d; sz[u] = ; cnt[u] = d;
for (int i = ; i < G[u].size(); i++){
int v = G[u][i];
if (v == fa) continue;
dfs_sz(v, u, d + );
sz[u] += sz[v];
cnt[u] += cnt[v];
}
} LL ans;
LL rest, res, addval;
///rest表示每次需要加回来的东西是多少,addval表示rest的和
///res表示把路上经过的点deep都变成1所剩下的val
LL pre[maxn];//表示深度为l的有多少节点是被修改了的
void dfs_solve(int u, int fa, int l, int r){
pre[deep[u]] = sz[u];
int L = deep[u] / + , R = deep[u];
if (R > r) res -= sz[u] * (deep[u] - );///减去子树的
if (L > l) rest -= pre[l];///减去之前子树的size
addval += rest;
ans = min(ans, addval + res);
for (int i = ; i < G[u].size(); i++){
int v = G[u][i];
if (v == fa) continue;
pre[deep[u]] -= sz[v];
rest += pre[deep[u]];
res += (deep[u] - ) * sz[v];
dfs_solve(v, u, L, R);
res -= (deep[u] - ) * sz[v];
rest -= pre[deep[u]];
pre[deep[u]] += sz[v];
}
if (R > r) res += sz[u] * (deep[u] - );
addval -= rest;
if (L > l) rest += pre[l];
} int main(){
int t; cin >> t;
while (t--){
scanf("%d", &n);
for (int i = ; i <= n; i++) G[i].clear();
for (int i = ; i < n; i++){
int u, v; scanf("%d%d", &u, &v);
G[u].pb(v), G[v].pb(u);
}
dfs_sz(, , );
res = ans = cnt[];
addval = ;
for (int i = ; i < G[].size(); i++){
int v = G[][i];
dfs_solve(v, , , );
}
printf("%lld\n", ans);
}
return ;
}
/*
456
7
1 2
2 3
3 4
3 5
5 7
4 6 ans = 12
*/

树dp...吧 ZOJ 3949的更多相关文章

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

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

  2. CF456D A Lot of Games (字典树+DP)

    D - A Lot of Games CF#260 Div2 D题 CF#260 Div1 B题 Codeforces Round #260 CF455B D. A Lot of Games time ...

  3. HDU4916 Count on the path(树dp??)

    这道题的题意其实有点略晦涩,定义f(a,b)为 minimum of vertices not on the path between vertices a and b. 其实它加一个minimum ...

  4. Codeforces 219D. Choosing Capital for Treeland (树dp)

    题目链接:http://codeforces.com/contest/219/problem/D 树dp //#pragma comment(linker, "/STACK:10240000 ...

  5. HDU4276 The Ghost Blows Light SPFA&&树dp

    题目的介绍以及思路完全参考了下面的博客:http://blog.csdn.net/acm_cxlove/article/details/7964739 做这道题主要是为了加强自己对SPFA的代码的训练 ...

  6. Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)

    [题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...

  7. HDU 3016 Man Down (线段树+dp)

    HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...

  8. bzoj 3572世界树 虚树+dp

    题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...

  9. bzoj 2286 [Sdoi2011]消耗战 虚树+dp

    题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...

随机推荐

  1. Thunder团队Final周贡献分分配结果

    小组名称:Thunder 项目名称:爱阅app 组长:王航 成员:李传康.翟宇豪.邹双黛.苗威.宋雨.胡佑蓉.杨梓瑞 分配规则 则1:基础分,拿出总分的20%(8分)进行均分,剩下的80%(32分)用 ...

  2. c# WPS DLL及其调用

    1.dll分享(含xsl及docx的dll) 链接:https://pan.baidu.com/s/1c1ImV14OndmvIb4W-_WL2A 密码:d2rx 2.方法: 1.先在类的前面(类外面 ...

  3. “我爱淘”第二冲刺阶段Scrum站立会议4

    完成任务: 完成了首页中的推荐功能,推荐的是最近添加的需要卖的书,注册功能实现了它,可以对数据库进行添加. 计划任务: 在客户端实现分类功能,通过学院的分类查看书籍. 遇到问题: 分类功能,根据不同学 ...

  4. 线段树---no end

    额,还有 :区间操作,交,并,补等 区间合并 扫描线 这些问题有空再研究吧.... 先看j2ee了..... 传送门 版权声明:本文为博主原创文章,未经博主允许不得转载.

  5. HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle  Accepts: 42  Submissions: 26 ...

  6. 201621123037 《Java学习设计》 第五周学习总结

    Week05-继承.多态.抽象类与接口 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:接口."has-a".多态.comparable.Compa ...

  7. yarn add & yarn global add

    yarn global add & add -D https://yarnpkg.com/zh-Hans/docs/cli/add#toc-commands $ yarn global add ...

  8. resp.getWriter().print的注意点

  9. BZOJ 2427 软件安装(强连通分量+树形背包)

    题意:现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大).但是现在有 ...

  10. Doves and bombs UVA - 10765(统计割顶所连接的连通块的数量)

    题意:给定一个n个点的连通的无向图,一个点的“鸽子值”定义为将它从图中删去后连通块的个数. 求对应的点 和 每个点的“鸽子值” 用一个数组在判断割顶的那个地方 累加标记一下所连接的连通块的数量即可 初 ...