树dp...吧 ZOJ 3949
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(u, v) 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 ≤ u, v ≤ 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的更多相关文章
- ZOJ 3949 Edge to the Root( 树形dp)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3949 题解:树dp真的很直觉,或者说dp真的很直觉.就上周末比赛时其实前一 ...
- 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 ...
- HDU4916 Count on the path(树dp??)
这道题的题意其实有点略晦涩,定义f(a,b)为 minimum of vertices not on the path between vertices a and b. 其实它加一个minimum ...
- Codeforces 219D. Choosing Capital for Treeland (树dp)
题目链接:http://codeforces.com/contest/219/problem/D 树dp //#pragma comment(linker, "/STACK:10240000 ...
- HDU4276 The Ghost Blows Light SPFA&&树dp
题目的介绍以及思路完全参考了下面的博客:http://blog.csdn.net/acm_cxlove/article/details/7964739 做这道题主要是为了加强自己对SPFA的代码的训练 ...
- Tsinsen A1219. 采矿(陈许旻) (树链剖分,线段树 + DP)
[题目链接] http://www.tsinsen.com/A1219 [题意] 给定一棵树,a[u][i]代表u结点分配i人的收益,可以随时改变a[u],查询(u,v)代表在u子树的所有节点,在u- ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- bzoj 3572世界树 虚树+dp
题目大意: 给一棵树,每次给出一些关键点,对于树上每个点,被离它最近的关键点(距离相同被标号最小的)控制 求每个关键点控制多少个点 分析: 虚树+dp dp过程如下: 第一次dp,递归求出每个点子树中 ...
- bzoj 2286 [Sdoi2011]消耗战 虚树+dp
题目大意:多次给出关键点,求切断边使所有关键点与1断开的最小费用 分析:每次造出虚树,dp[i]表示将i和i子树与父亲断开费用 对于父亲x,儿子y ①y为关键点:\(dp[x]\)+=\(dismn( ...
随机推荐
- 【每日scrum】NO.8
(1) 在图的设计过程中掌握了图的基本运算函数的算法的理解和程序的有效吸收,包括图的深度和广度优先的遍历,对图的联通分量的求解,图的最小生成树,图的拓扑排序,图的关键路径, (2)在迪杰斯特拉算法的基 ...
- ARP 攻击
场景 A攻击者 192.168.1.3 00:00:00:00:00:01 B受害者 192.168.1.2 00:00:00:00:00:02 C路由器 192.168.1.1 00:00:00:0 ...
- lintcode-450-K组翻转链表
450-K组翻转链表 给你一个链表以及一个k,将这个链表从头指针开始每k个翻转一下. 链表元素个数不是k的倍数,最后剩余的不用翻转. 样例 给出链表 1->2->3->4->5 ...
- Qt使用QNetworkAccessManager实现Http操作
版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt使用QNetworkAccessManager实现Http操作 本文地址:http ...
- PHP简单模拟登录功能实例分享
1.curl实现模拟登录的代码,(只是实现服务器与服务器建立会话,其实并没有在客户端与服务器之间建立会话) <?php $cookie_jar = tempnam('./tmp','cookie ...
- java之静态代理与动态代理
先看看静态代理是如何操作的 定义接口: public interface Person { public void sayHello(String content, int age); public ...
- 虚拟机中安装 centOS,本地安装 SSH 连接 - 01
下面把自己安装 centOS 的过程记录下,选取的版本是 centOS6.8 ,下载地址在脚本之家 down 的 : 阿里云 x64 http://mirrors.aliyun.com/centos/ ...
- 【bzoj1297】[SCOI2009]迷路 矩阵乘法
题目描述 给出一个 $n$ 个点的有向图,每条边的权值都在 $[1,9]$ 之间.给出 $t$ ,求从 $1$ 到 $n$ ,经过路径边权和恰好为 $t$ 的方案数模2009. 输入 第一行包含两个整 ...
- 小结ospf基本配置的三个参数
实例:<华为路由器学习指南>P712 OSPF基本功能配置示例拓扑结构 配置思路:以E为例子 [E]ospf 100 router-id 5.5.5.5[E-ospf-100]area 1 ...
- 【JQuery】文档操作
一.前言 接着上一章的内容,接着JQuery的学习 二.内容 addClass 向被选元素添加一个或多个类 $(selector).addClass(class) $(selector).addCla ...