ZOJ 3949 Edge to the Root
题意:
在一棵树中,可以从根节点往其他节点加一条边,使得根节点到其他所有节点的距离和最小,输出最小的距离和。
思路:
我们考虑在加的一条边为$1 \to v$,那么在树上从$1 \to v$的路径上,如果有一个点$y$到$v$比到$1$更近,那么这个点$y$的子树里的所有
点都到$v$更近。那么我们找到离根最近的点$y$,那么$y$子树中的所有点都是到$v$更近。
我们考虑:
$f[u]$表示如果添加了$1 \to u$这条边的最小距离和是多少。
$g[u]$表示如果添加了$1 \to u$这条边有多少点到$u$的距离比到根的距离更小。
$sze[u]$表示$u$的子树的大小。
那么对于它的一个儿子$v$,$f[v] = f[u] - 2 \cdot sze[v] + g[u]$。
因为原来到$u$更优的,那么到$v$至少不会比到根更差,但是$v$的子树中的贡献要重新算。
然后更新一下儿子节点的$g[u]$就好了,这个时候到$v$和到根一样优的点就被删去了。
#include <bits/stdc++.h>
using namespace std; #define ll long long
#define N 200010
#define INFLL 0x3f3f3f3f3f3f3f3f
#define DEG 20
int n;
vector <int> G[N]; int dep[N], fa[DEG][N], sze[N], k[N];
void DFS1(int u)
{
k[u] = (dep[u]) / - ;
for (int i = ; i < DEG; ++i)
fa[i][u] = fa[i - ][fa[i - ][u]];
sze[u] = ;
for (auto v : G[u]) if (v != fa[][u])
{
fa[][v] = u;
dep[v] = dep[u] + ;
DFS1(v); sze[u] += sze[v];
}
} int findkth(int u, int k)
{
for (int i = DEG - ; i >= ; --i)
if ((k >> i) & )
u = fa[i][u];
return u;
} int f[N]; ll g[N], res;
void DFS2(int u)
{
if (u != )
{
if (dep[u] <= )
{
f[u] = sze[u];
g[u] = g[] - 1ll * (dep[u] - ) * sze[u];
}
else
{
int pre = fa[][u];
g[u] = g[pre] - * sze[u] + f[pre];
f[u] = sze[findkth(u, k[u])];
}
}
res = min(res, g[u]);
for (auto v : G[u]) if (v != fa[][u])
DFS2(v);
} int main()
{
int T; cin >> T;
while (T--)
{
scanf("%d", &n);
for (int i = ; i <= n; ++i) G[i].clear();
memset(sze, , sizeof sze);
for (int i = , u, v; i < n; ++i)
{
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
dep[] = ; DFS1();
res = INFLL;
g[] = ;
for (int i = ; i <= n; ++i)
g[] += dep[i];
DFS2();
printf("%lld\n", res);
}
return ;
}
ZOJ 3949 Edge to the Root的更多相关文章
- 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 ...
 - ZOJ 3949  Edge to the Root( 树形dp)
		
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3949 题解:树dp真的很直觉,或者说dp真的很直觉.就上周末比赛时其实前一 ...
 - ZOJ 3949 Edge to the Root(树形DP)
		
[题目链接] http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3949 [题目大意] 给出一棵根为1的树,每条边边长为1,请你 ...
 - 树dp...吧 ZOJ 3949
		
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5568 Edge to the Root Time Limit: 1 Secon ...
 - POJ 3100 & ZOJ 2818 & HDU 2740 Root of the Problem(数学)
		
题目链接: POJ:id=3100" style="font-size:18px">http://poj.org/problem? id=3100 ZOJ:http ...
 - ZOJ 3949 (17th 浙大校赛 B题,树型DP)
		
题目链接 The 17th Zhejiang University Programming Contest Problem B 题意 给定一棵树,现在要加一条连接$1$(根结点)和$x$的边,求加 ...
 - ZOJ 2048(Prim 或者 Kruskal)
		
Highways Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge The island nation of F ...
 - imx6 gpio irq
		
/***************************************************************** * gpio irq * * 一直以来都没了解过gpio的irq, ...
 - 【BZOJ-3697&3127】采药人的路径&YinandYang        点分治 + 乱搞
		
3697: 采药人的路径 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 681 Solved: 246[Submit][Status][Discus ...
 
随机推荐
- SocketAsyncEventArgs的释放问题
			
起因是发现一个同事编写的程序运行两个月左右,占用了服务器20G左右的内存.用WinDbg查看发现存在大量的Async Pinned Handles,而它们的gcroot都来自于SocketAsyncE ...
 - facebook login issue
			
If enable the facebook account in settings, when change account can't open the session. -(void)fbRes ...
 - Centos 7.x临时的网络与路由配置
			
今天在虚拟机上安装了Centos 7.1操作系统,使用的最小化安装,安装完成后准备使用ifconfig命令时,发现命令不存在,如下: 心想肯定是新版的Centos 系统默认情况下没有使用ifconfi ...
 - 【CF799E】Aquarium decoration 线段树
			
[CF799E]Aquarium decoration 题意:有n个物品,小A和小B各自喜欢其中的某些物品,一件物品可能既被小A喜欢又被小B喜欢,也可能既不被小A喜欢又不被小B喜欢.每个物品都有一个价 ...
 - 几种在Linux下查询外网IP的办法(转)
			
Curl 纯文本格式输出: curl icanhazip.com curl ifconfig.me curl curlmyip.com curl ip.appspot.com curl ipinfo. ...
 - 关于IP地址子网的划分
 - 9.6Django
			
2018-9-6 12:56:32 2018-9-6 18:32:22 把那个用户列表的页面优化了一下!用了老师更好看的页面,但是功能还是那些! 就是修改一下url就好! 放在我我的github : ...
 - 浅析JSONP
			
什么是JSONP? JSONP是JSON with Padding的略称.它是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式 ...
 - poj3728The merchant 【倍增】【LCA】
			
There are N cities in a country, and there is one and only one simple path between each pair of citi ...
 - python 全局变量引用与修改
			
一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if ...