题目描述 Description
 给一棵N个节点的无根树,求路径长度=K的简单路径数
输入描述 Input Description

第一行两个正整数N,K

接下来N-1行,每行两个正整数x,y,表示一条边(x,y)

输出描述 Output Description
一行一个整数,答案
样例输入 Sample Input
4 2
1 2
2 3
2 4
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
对于30% 2<=K,N<=1000

对于100%,2<=K,N<=10^5

还是一道点分治的题,和POJ1741唯一的区别就是一个是找路径<=k的,一个是找等于k的。两个算法唯一的区别就是在处理dis数组的区别。对于在一个有序表中O(n)的求数对满足两个数的和等于K,我想不到什么比较好的方法,所以导致处理算ans时写的比较丑。

#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long LL;
#define Pi acos(-1.0)
inline int read()
{
int x=,f=;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-;c=getchar();}
while(isdigit(c)){x=x*+c-'';c=getchar();}
return x*f;
}
const int maxn=;
struct Edge
{
int u,v,next;
Edge() {}
Edge(int _1,int _2,int _3) : u(_1),v(_2),next(_3) {}
}e[*maxn];
int first[maxn],n,k,a,b,size[maxn],masize[maxn],now_size,root,dis[maxn],end;
bool vis[maxn];
LL ans;
void addEdge(int i,int a,int b)
{
e[i]=Edge(a,b,first[a]);
first[a]=i;
}
void gets(int u,int pa)
{
size[u]=;
masize[u]=;
for(int i=first[u];i!=-;i=e[i].next)
if(!vis[e[i].v] && e[i].v!=pa)
{
gets(e[i].v,u);
size[u]+=size[e[i].v];
masize[u]=max(size[e[i].v],masize[u]);
}
}
void getr(int r,int u,int pa)
{
masize[u]=max(masize[u],size[r]-size[u]);
if(masize[u]<now_size)now_size=masize[u],root=u;
for(int i=first[u];i!=-;i=e[i].next)
if(!vis[e[i].v] && e[i].v!=pa)getr(r,e[i].v,u);
}
void getd(int u,int pa,int d)
{
dis[end++]=d;
for(int i=first[u];i!=-;i=e[i].next)
if(!vis[e[i].v] && e[i].v!=pa)getd(e[i].v,u,d+);
}
LL calc(int u,int d)
{
end=;
getd(u,-,d);
LL ret=;
int l=,r=end-,L,R;
sort(dis,dis+end);
// cout<<u<<":";
// for(int i=0;i<end;i++)cout<<dis[i]<<' ';
// cout<<endl;
while(l<r)
{
while(dis[l]+dis[r]>k && l<r)r--;
if(dis[l]+dis[r]==k)
{
if(dis[l]==dis[r])
{
ret+=((LL)(r-l+)*(LL)(r-l)/);
break;
}
else
{
L=R=;
while(dis[r-]==dis[r])r--,R++;
while(dis[l+]==dis[l])l++,L++;
ret+=((LL)L*(LL)R);L=R=;
r--;l++;
}
}
else l++;
}
return ret;
}
void dfs(int u)
{
now_size=n;
gets(u,-);
getr(u,u,-);
ans+=calc(root,);
vis[root]=;
for(int i=first[root];i!=-;i=e[i].next)
if(!vis[e[i].v])
{
ans-=calc(e[i].v,);
dfs(e[i].v);
}
return;
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
memset(first,-,sizeof(first));
n=read();k=read();
for(int i=;i<n-;i++)
{
a=read();b=read();
addEdge(i*,a,b);addEdge(i*+,b,a);
}
dfs();
printf("%lld\n",ans);
return ;
}

[冬令营day1T3]Tree的更多相关文章

  1. 牛客网字节跳动冬令营网络赛J Sortable Path on Tree —— 点分治

    题目:https://ac.nowcoder.com/acm/contest/296/J 用点分治: 记录了值起伏的形态,二元组 (x,y) 表示有 x 个小于号,y 个大于号: 因为小于号和大于号都 ...

  2. NOI2019冬令营报到通知

    由中国计算机学会(CCF)主办的2019全国青少年信息学奥林匹克冬令营(CCF NOI 2019冬令营)将于2019年1月24日-31日在广州市第二中学举行.其中1月24日为报到日,1月31日为疏散日 ...

  3. 数学-Matrix Tree定理证明

    老久没更了,冬令营也延期了(延期后岂不是志愿者得上学了?) 最近把之前欠了好久的债,诸如FFT和Matrix-Tree等的搞清楚了(啊我承认之前只会用,没有理解证明--),FFT老多人写,而Matri ...

  4. [特别篇] 记JZ冬令营(Finished)

    1.16 走错班了, 去了全是大佬的1班, 然后灰溜溜滚回2班了. 去参加开营仪式. 然而昏昏欲睡... 实在太累了澡也没洗.. 群英云集, 多是感慨. 当时依依惜别和铮铮誓言, 在重逢中无语凝噎. ...

  5. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  6. SAP CRM 树视图(TREE VIEW)

    树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...

  7. 无限分级和tree结构数据增删改【提供Demo下载】

    无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...

  8. 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>

    在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...

  9. Leetcode 笔记 110 - Balanced Binary Tree

    题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...

随机推荐

  1. LeetCode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix (最少翻转次数将二进制矩阵全部置为0)

    给一个矩阵mat,每个格子都是0或1,翻转一个格子会将该格子以及相邻的格子(有共同边)全部翻转(0变为1,1变为0) 求问最少需要翻转几次将所有格子全部置为0. 这题的重点是数据范围,比赛结束看了眼数 ...

  2. mysql数据库备份工具xtrabackup

    1.下载二进制安装包 其他高版本测试缺少依赖 2.xtrabackup参数说明 简介:  Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工 ...

  3. # Leetcode 14:Longest Common Prefix 最长公共前缀

    公众号:爱写bug Write a function to find the longest common prefix string amongst an array of strings. If ...

  4. SpringBoot整合mybatis及注意事项

    SpringBoot整合mybatis及注意事项 主要步骤 添加依赖 mybatis 在配置文件中配置数据源信息 编写pojo mapper接口 mapeer映射文件 手动配置mybatis的包扫描 ...

  5. Java匹马行天下之JavaSE核心技术——注解

    Java注解 一.什么是注解 注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,没有加,则等于没有任何标记,以后,javac编译器.开发工具和其他程序可以通过反射来 ...

  6. 1 Python命令行参数(脚本神器)

    #!/usr/bin/env python3.7 # -*- coding:utf-8 -*- # Author: Lancer 2019-09-02 10:07:21 import sys,geto ...

  7. vue 强制刷新 demo 神器

    this.$forceUpdate() /*关键句,强制更新dom*/

  8. 阅读prettytable 一些代码、get、set 检查参数

    阅读代码是因为我发现官方教程里的代码在本地不能用,所以就通过”查看定义“转到了源代码里. 通过阅读源代码,查看方法内是否有教程中所说的方法名和参数名,然后再通过”查看引用“来试图了解函数的流程,如果没 ...

  9. 线程池---Day26

    线程池思想概述 当我们要使用线程的时候就去创建一个线程时,虽然实现方便,但是会出现问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率, ...

  10. Scanner 中next()和nexline()方法的区别

      在java实现字符窗口的输入时,很多人更喜欢选择使用扫描器scanner,它操作起来比较简单.在编程的过程中,我发现用scanner实现字符串的输入有两种方法,一种是next(),另一种是next ...