CodeForces161D: Distance in Tree(树分治)
A tree is a connected graph that doesn't contain any cycles.
The distance between two vertices of a tree is the length (in edges) of the shortest path between these vertices.
You are given a tree with n vertices and a positive number k. Find the number of distinct pairs of the vertices which have a distance of exactly k between them. Note that pairs (v, u) and (u, v) are considered to be the same pair.
Input
The first line contains two integers n and k (1 ≤ n ≤ 50000, 1 ≤ k ≤ 500) — the number of vertices and the required distance between the vertices.
Next n - 1 lines describe the edges as "ai bi" (without the quotes) (1 ≤ ai, bi ≤ n, ai ≠ bi), where ai and bi are the vertices connected by the i-th edge. All given edges are different.
Output
Print a single integer — the number of distinct pairs of the tree's vertices which have a distance of exactly k between them.
Please do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.
Examples
5 2
1 2
2 3
3 4
2 5
4
5 3
1 2
2 3
3 4
4 5
2
题意:给定一棵树,问树上有多少个点对距离是K(K<=500)。
思路:明显的基础分治题,分别累计经过根节点的距离为K的点对。说他基础是以为既不需要排序,也不需要去重。复杂度O(NlogN*K)
(感悟:分治=若干个小分治+线性解决当前层 =NlogN。
分治=若干个小分治+logN解决当前层 =NlogN*logN。
分治=若干个小分治+K*线性解决当前层 =N*K*logN。
#include<bits/stdc++.h>
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn];
int sz[maxn],son[maxn],root,cnt,N,K,ans,sn; //sn,小树的大小。
int num[],tnum[],vis[maxn];
void read(int &x){
x=; char c=getchar();
while(c>''||c<'') c=getchar();
while(c>=''&&c<='') x=(x<<)+(x<<)+c-'',c=getchar();
}
void add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt; To[cnt]=v;
}
void getroot(int u,int fa)
{
sz[u]=; son[u]=;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(v==fa||vis[v]) continue;
getroot(v,u); sz[u]+=sz[v];
son[u]=max(son[u],sz[v]);
}
son[u]=max(sz[u],sn-son[u]);
if(root==||son[root]>son[u]) root=u;
}
void getdep(int u,int fa,int dis)
{
if(K>=dis) ans+=num[K-dis],tnum[dis]++;
if(K==dis) return ;
for(int i=Laxt[u];i;i=Next[i])
if(To[i]!=fa&&!vis[To[i]])
getdep(To[i],u,dis+);
}
void dfs(int u)
{
vis[u]=;
for(int i=;i<=K;i++) num[i]=; num[]=;
for(int i=Laxt[u];i;i=Next[i]){ //暴力部分
if(vis[To[i]]) continue;
for(int j=;j<=K;j++) tnum[j]=;
getdep(To[i],,);
for(int j=;j<=K;j++) num[j]+=tnum[j];
} for(int i=Laxt[u];i;i=Next[i]){ //以大化小,分治部分
if(vis[To[i]]) continue;
sn=sz[To[i]]; root=;
getroot(To[i],u); dfs(root);
}
}
int main()
{
int u,v; scanf("%d%d",&N,&K);
for(int i=;i<N;i++){
read(u) ; read(v) ;
add(u,v); add(v,u);
}
root=; sn=N; getroot(,); dfs(root);
printf("%d\n",ans);
return ;
}
CodeForces161D: Distance in Tree(树分治)的更多相关文章
- CodeChef - PRIMEDST Prime Distance On Tree 树分治 + FFT
Prime Distance On Tree Problem description. You are given a tree. If we select 2 distinct nodes unif ...
- [codeforces161D]Distance in Tree(点分治/树形dp)
题意:求树上距离为k的点对个数: 解题关键:练习一下点分治不用容斥 而直接做的做法.注意先查询,后更新. 不过这个方法有个缺陷,每次以一个新节点为根,必须memset mp数组,或许使用map会好些, ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- POJ 1741.Tree 树分治 树形dp 树上点对
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 24258 Accepted: 8062 Description ...
- poj 1744 tree 树分治
Tree Time Limit: 1000MS Memory Limit: 30000K Description Give a tree with n vertices,each ed ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- HDU4871 Shortest-path tree(树分治)
好久没做过树分治的题了,对上一次做是在南京赛里跪了一道很裸的树分治题后学的一道,多校的时候没有看这道题,哪怕看了感觉也看不出来是树分治,看出题人给了解题报告里写了树分治就做一下好了. 题意其实就是给你 ...
- HDU4670 Cube number on a tree 树分治
人生的第一道树分治,要是早点学我南京赛就不用那么挫了,树分治的思路其实很简单,就是对子树找到一个重心(Centroid),实现重心分解,然后递归的解决分开后的树的子问题,关键是合并,当要合并跨过重心的 ...
- Codeforces 161D Distance in Tree(树型DP)
题目链接 Distance in Tree $k <= 500$ 这个条件十分重要. 设$f[i][j]$为以$i$为子树,所有后代中相对深度为$j$的结点个数. 状态转移的时候,一个结点的信息 ...
随机推荐
- hdu 4857 逆拓扑+大根堆(priority_queue)
题意:排序输出:在先满足定约束条件下(如 3必需在1前面,7必需在4前面),在满足:1尽量前,其次考虑2,依次.....(即有次约束). 开始的时候,只用拓扑,然后每次在都可以选的时候,优先考虑小的, ...
- STM32 GPIO寄存器 IDR ODR BSRR BRR
IDR是查看引脚电平状态用的寄存器,ODR是引脚电平输出的寄存器 下面内容的原文:http://m646208823.blog.163.com/blog/static/1669029532012931 ...
- Ubuntu 16.04下快速在当前目录打开终端的快捷键设置
说明:不一定每次都准确打开,80%的机会是行的. 原理:使用xdotool模拟键盘按键,打开的文件夹管理界面,然后通过Ctrl+L获取地址栏地址,然后传递到终端上. 安装: 1.安装xdotool s ...
- Spring MVC入门实例
1.web.xml配置 <?xml version="1.0" encoding="UTF-8"? > <web-app xmlns:xsi= ...
- 一起学习CMake – 01
一起学习CMake – 01 本节介绍CMake里最常用的三个命令,分别是cmake_minimum_required; project; add_executable等. CMake是个好东西,在使 ...
- Raspberry Pi学习笔记
一.树莓派 Raspberry Pi 更换国内源 编辑 /etc/apt/sources.list 文件,用 nano 命令编辑 pi@raspberrypi:~$ sudo cp /etc/apt/ ...
- call lua function from c and called back to c
Just a simple example: --The c file: #include <stdio.h> #include "lua.h" #include & ...
- hadoop-mapreduce中reducetask执行分析
ReduceTask的执行 Reduce处理程序中须要运行三个类型的处理, 1.copy,从各map中copy数据过来 2.sort,对数据进行排序操作. 3.reduce,运行业务逻辑的处理. Re ...
- C#获取电脑的相关信息
/* 创建者:菜刀居士的博客 * 创建日期: 2014年08月31号 * 功能:获取电脑的相关信息 * */ namespace Net.String.ConsoleApplication { ...
- C++写动态站点之HelloWorld!
演示样例源码下载地址:Fetch_Platform.7z 更复杂的代码可參考本博客BBS的实现 简单的说.动态站点就是能够动态变更的站点.动态变化的内容通常来自后端数据库.例如以下省略万字(动态站点) ...