传送门:https://codeforces.com/problemset/problem/161/D

题意:

求树上点对距离恰好为k的点对个数

题解:

与poj1741相似

把点分治的模板改一下即可,我们依然是求得一个dep数组,然后根据这个dep数组来更新两点间的距离,由于k的范围只有500,所以我们可以直接开一个500的数组来统计两点间距离的数量

代码:

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define ls rt<<1
#define rs rt<<1|1
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define bug printf("*********\n")
#define FIN freopen("input.txt","r",stdin);
#define FON freopen("output.txt","w+",stdout);
#define IO ios::sync_with_stdio(false),cin.tie(0)
#define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n"
#define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n"
#define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n"
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
struct EDGE {
int v, w, nxt;
} edge[maxn << 1];
int head[maxn], tot;
void add_edge(int u, int v, int w) {
edge[tot].v = v;
edge[tot].w = w;
edge[tot].nxt = head[u];
head[u] = tot++;
}
int sz[maxn], son[maxn], dep[maxn], vis[maxn];
int Maxt, root, Allnode, cnt;
LL ans;
int n, k; void get_root(int u, int fa) {
sz[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].nxt) {
int v = edge[i].v;
if(!vis[v] && v != fa) {
get_root(v, u);
sz[u] += sz[v];
}
}
int tmp = max(sz[u] - 1, Allnode - sz[u]);
if(Maxt > tmp) Maxt = tmp, root = u;
}
void dfs(int u, int fa, int len, int dis) {
dep[++cnt] = dis;
if(dis >= len) return;
for(int i = head[u]; i != -1; i = edge[i].nxt) {
int v = edge[i].v;
if(!vis[v] && v != fa) {
dfs(v, u, len, dis + 1);
}
}
}
LL cal(int rt, int fa, int len) {
if(len <= 0) return len == 0;
cnt = 0;
dfs(rt, fa, len, 0);
LL res = 0;
int num[505]{};
for(int i = 1; i <= cnt; i++) {
num[dep[i]]++;
}
for(int i = 1; i <= cnt; i++) {
res += num[len - dep[i]];
}
return res;
}
void divide(int rt) {
vis[rt] = 1;
// debug1(ans);
ans += cal(rt, 0, k);
for(int i = head[rt]; i != -1; i = edge[i].nxt) {
int v = edge[i].v;
if(!vis[v]) {
ans -= cal(v, rt, k - 2);
Allnode = sz[v];
Maxt = n;
get_root(v, rt);
divide(root);
}
}
}
int main() {
#ifndef ONLINE_JUDGE
FIN
#endif
while(scanf("%d%d", &n, &k) != EOF) {
memset(head, -1, sizeof(head));
tot = 0;
for(int i = 1, u, v; i < n; i++) {
scanf("%d%d", &u, &v);
add_edge(u, v, 1);
add_edge(v, u, 1);
}
memset(vis, 0, sizeof(vis));
Allnode = n;
Maxt = INF;
get_root(1, 0);
divide(root);
printf("%lld\n", ans/2);
}
return 0;
}

codeforces 161D 点分治的更多相关文章

  1. Distance in Tree CodeForces - 161D

    Distance in Tree CodeForces - 161D 题意:给一棵n个结点的树,任意两点之间的距离为1,现在有点u.v,且u与v的最短距离为k,求这样的点对(u,v)的个数((u,v) ...

  2. codeforces 161D Distance in Tree 树上点分治

    链接:https://codeforces.com/contest/161/problem/D 题意:给一个树,求距离恰好为$k$的点对是多少 题解:对于一个树,距离为$k$的点对要么经过根节点,要么 ...

  3. Codeforces 161D Distance in Tree(树的点分治)

    题目大概是,给一棵树,统计距离为k的点对数. 不会DP啊..点分治的思路比较直观,啪啪啪敲完然后AC了.具体来说是这样的: 树上任何两点的路径都可以看成是一条过某棵子树根的路径,即任何一条路径都可以由 ...

  4. Codeforces 293E 点分治+cdq

    Codeforces 293E 传送门:https://codeforces.com/contest/293/problem/E 题意: 给你一颗边权一开始为0的树,然后给你n-1次操作,每次给边加上 ...

  5. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

  6. Codeforces 475D CGCDSSQ(分治)

    题意:给你一个序列a[i],对于每个询问xi,求出有多少个(l,r)对使得gcd(al,al+1...ar)=xi. 表面上是询问,其实只要处理出每个可能的gcd有多少个就好了,当左端点固定的时候,随 ...

  7. Codeforces 161D Distance in Tree

    题目大意:给出一棵n个节点的树,统计树中长度为k的路径的条数(1<=n<=50000 , 1<=k<=500) 思路:树分治! #include<cstdio> # ...

  8. Codeforces 888G(分治+trie)

    按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...

  9. Codeforces 888G Xor-MST - 分治 - 贪心 - Trie

    题目传送门 这是一条通往vjudge的高速公路 这是一条通往Codeforces的高速公路 题目大意 给定一个$n$阶完全图,每个点有一个权值$a_{i}$,边$(i, j)$的权值是$(a_{i}\ ...

随机推荐

  1. 从零学React Native之14 网络请求

    通过HTTP或者HTTPS协议与网络侧服务器交换数据是移动应用中常见的通信方式. node-fetch是RN推荐的请求方式. React Native框架在初始化项目时, 引入了node-fetch包 ...

  2. Extended Traffic

    题目链接 题意:有n个路口,m条通路,如果经过一条路则会得到(终点 - 起点)^3的权值,求从1点到其他点的最小权值,如果权值小于3或无法到达输出'?'. 题解:因为权值可能为负,所以用SPFA来解题 ...

  3. python 类与类之间的关系. 特殊成员

    一.类与类之间的关系 1.依赖关系 在方法的参数位置把另一个类的对象作为参数进行传递 class Person: def play(self, tools): # 通过参数的传递把另一个类的对象传递进 ...

  4. HDU 5672 String【尺取法】

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5672 题意: 有一个10≤长度≤1,000,000的字符串,仅由小写字母构成.求有多少个子串,包含有 ...

  5. SDUT-2118_数据结构实验之链表三:链表的逆置

    数据结构实验之链表三:链表的逆置 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 输入多个整数,以-1作为结束标志,顺序 ...

  6. Java中的Runnable、Callable、Future、FutureTask的区别与示例

    Java中存在Runnable.Callable.Future.FutureTask这几个与线程相关的类或者接口,在Java中也是比较重要的几个概念,我们通过下面的简单示例来了解一下它们的作用于区别. ...

  7. 20182019-acmicpc-asia-dhaka-regional F .Path Intersection 树链剖分

    直接进行树链剖分,每次对路径区间内的所有点值+1,线段树进行维护,然后查询线段树的最大值的个数!!! 查询线段树区间最大值个数,可以先维护区间和,在维护区间最值,如果区间和等于区间最值乘以区间长度,那 ...

  8. hdu 1289 Hat’s IEEE

    Problem - 1289 好题.其实就是模拟IEEE754的格式,不过要注意的是,这里用的32位是float,用double就不对了. 代码如下: #include <cstdio> ...

  9. 我爱自然语言处理bert ner chinese

    BERT相关论文.文章和代码资源汇总 4条回复 BERT最近太火,蹭个热点,整理一下相关的资源,包括Paper, 代码和文章解读. 1.Google官方: 1) BERT: Pre-training ...

  10. Activity学习(一):生命周期

    一. 认识Activity Activity是Android的四大组件之一,那么它是什么呢?如果简单的理解,可以把它当成应用的一个显示的屏幕. Activity类处于android.app包中,继承体 ...