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. 20181009-3 Scrum立会报告+燃尽图02

    此作业要求:[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2190] 一.小组介绍 组长:王一可 组员:范靖旋,王硕,赵佳璐,范洪达,祁 ...

  2. struts2 不返回result的做法

    有时候 比如提交一个弹框的表单 提交成功后我们只是让表单关闭并不进行页面跳转,那么action 里面就returne null, 然后result 也不用配置了 版权声明:本文为博主原创文章,未经博主 ...

  3. [codecademy]css

    Great work! You've learned the basics of CSS structure and syntax. We'll continue to build on these ...

  4. lintcode-450-K组翻转链表

    450-K组翻转链表 给你一个链表以及一个k,将这个链表从头指针开始每k个翻转一下. 链表元素个数不是k的倍数,最后剩余的不用翻转. 样例 给出链表 1->2->3->4->5 ...

  5. mysql-otp 驱动中设置utf8mb4

    utf8mb4支持emoji表情,在mysql中设置连接字符集为utf8mb4可以直接储存emoji表情. 可以在客户端连接中设置: SET NAMES utf8mb4 查看是否起效: SHOW VA ...

  6. Alpha阶段事后诸葛亮分析

    事后诸葛亮分析 一.设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件可供各类人群闲暇时间消遣娱乐,锻炼脑力. 定义的很清楚,就是一个定位 ...

  7. 解决 Package test is missing dependencies for the following libraries: libcrypto.so.1.0.0

    根据项目要求需要用到openssl这个库,看了看编译环境幸好本身就集成了该库.但在编译openssl的功能时,碰到缺少类库的错误. Package test is missing dependenci ...

  8. 【ASP.NET Core】ASP.NET Core 依赖注入

    一.什么是依赖注入(Denpendency Injection) 这也是个老身常谈的问题,到底依赖注入是什么? 为什么要用它? 初学者特别容易对控制反转IOC(Iversion of Control) ...

  9. Java内存区域介绍

    Java虚拟机把内存划分成几个区域,每个区域都有各自的职责.下面将逐一分析每个区域. 有助于我们了解,每个方法,变量,对象等都去哪儿了! 程序计数器: 它占用一块很小的内存空间,可以看作是当前线程所执 ...

  10. BZOJ4878 挑战NP-Hard(dfs树)

    既然是二选一,考虑两个问题有什么联系.题面没有说无解怎么办,所以如果不存在经过k条边的简单路径,一定存在k染色方案.考虑怎么证明这个东西,我们造一棵dfs树.于是可以发现如果树深>k(根节点深度 ...