[冬令营day1T3]Tree
|
题目描述 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的更多相关文章
- 牛客网字节跳动冬令营网络赛J Sortable Path on Tree —— 点分治
题目:https://ac.nowcoder.com/acm/contest/296/J 用点分治: 记录了值起伏的形态,二元组 (x,y) 表示有 x 个小于号,y 个大于号: 因为小于号和大于号都 ...
- NOI2019冬令营报到通知
由中国计算机学会(CCF)主办的2019全国青少年信息学奥林匹克冬令营(CCF NOI 2019冬令营)将于2019年1月24日-31日在广州市第二中学举行.其中1月24日为报到日,1月31日为疏散日 ...
- 数学-Matrix Tree定理证明
老久没更了,冬令营也延期了(延期后岂不是志愿者得上学了?) 最近把之前欠了好久的债,诸如FFT和Matrix-Tree等的搞清楚了(啊我承认之前只会用,没有理解证明--),FFT老多人写,而Matri ...
- [特别篇] 记JZ冬令营(Finished)
1.16 走错班了, 去了全是大佬的1班, 然后灰溜溜滚回2班了. 去参加开营仪式. 然而昏昏欲睡... 实在太累了澡也没洗.. 群英云集, 多是感慨. 当时依依惜别和铮铮誓言, 在重逢中无语凝噎. ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- SAP CRM 树视图(TREE VIEW)
树视图可以用于表示数据的层次. 例如:SAP CRM中的组织结构数据可以表示为树视图. 在SAP CRM Web UI的术语当中,没有像表视图(table view)或者表单视图(form view) ...
- 无限分级和tree结构数据增删改【提供Demo下载】
无限分级 很多时候我们不确定等级关系的层级,这个时候就需要用到无限分级了. 说到无限分级,又要扯到递归调用了.(据说频繁递归是很耗性能的),在此我们需要先设计好表机构,用来存储无限分级的数据.当然,以 ...
- 2000条你应知的WPF小姿势 基础篇<45-50 Visual Tree&Logic Tree 附带两个小工具>
在正文开始之前需要介绍一个人:Sean Sexton. 来自明尼苏达双城的软件工程师.最为出色的是他维护了两个博客:2,000Things You Should Know About C# 和 2,0 ...
- Leetcode 笔记 110 - Balanced Binary Tree
题目链接:Balanced Binary Tree | LeetCode OJ Given a binary tree, determine if it is height-balanced. For ...
随机推荐
- LeetCode 1284. Minimum Number of Flips to Convert Binary Matrix to Zero Matrix (最少翻转次数将二进制矩阵全部置为0)
给一个矩阵mat,每个格子都是0或1,翻转一个格子会将该格子以及相邻的格子(有共同边)全部翻转(0变为1,1变为0) 求问最少需要翻转几次将所有格子全部置为0. 这题的重点是数据范围,比赛结束看了眼数 ...
- mysql数据库备份工具xtrabackup
1.下载二进制安装包 其他高版本测试缺少依赖 2.xtrabackup参数说明 简介: Xtrabackup是一个对InnoDB做数据备份的工具,支持在线热备份(备份时不影响数据读写),是商业备份工 ...
- # Leetcode 14:Longest Common Prefix 最长公共前缀
公众号:爱写bug Write a function to find the longest common prefix string amongst an array of strings. If ...
- SpringBoot整合mybatis及注意事项
SpringBoot整合mybatis及注意事项 主要步骤 添加依赖 mybatis 在配置文件中配置数据源信息 编写pojo mapper接口 mapeer映射文件 手动配置mybatis的包扫描 ...
- Java匹马行天下之JavaSE核心技术——注解
Java注解 一.什么是注解 注解(Annotation)相当于一种标记,在程序中加入注解就等于为程序打上某种标记,没有加,则等于没有任何标记,以后,javac编译器.开发工具和其他程序可以通过反射来 ...
- 1 Python命令行参数(脚本神器)
#!/usr/bin/env python3.7 # -*- coding:utf-8 -*- # Author: Lancer 2019-09-02 10:07:21 import sys,geto ...
- vue 强制刷新 demo 神器
this.$forceUpdate() /*关键句,强制更新dom*/
- 阅读prettytable 一些代码、get、set 检查参数
阅读代码是因为我发现官方教程里的代码在本地不能用,所以就通过”查看定义“转到了源代码里. 通过阅读源代码,查看方法内是否有教程中所说的方法名和参数名,然后再通过”查看引用“来试图了解函数的流程,如果没 ...
- 线程池---Day26
线程池思想概述 当我们要使用线程的时候就去创建一个线程时,虽然实现方便,但是会出现问题:如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率, ...
- Scanner 中next()和nexline()方法的区别
在java实现字符窗口的输入时,很多人更喜欢选择使用扫描器scanner,它操作起来比较简单.在编程的过程中,我发现用scanner实现字符串的输入有两种方法,一种是next(),另一种是next ...