题目:https://www.acwing.com/problem/content/254/

题意:求一棵树上,路径<=k的有多少条

思路:点分治,我们用两个指针算solve函数,首先对算出来的路径每个排个序,我们就保证有单调性,然后l从前往后,r从后往前,如果l+r<=m  那么(l,r-1) (l,r-2)...都是可以的,直接加上总数即可,如果不满足 r--,满足l++,这个自己写个例子就能明白的

#include<bits/stdc++.h>
#define maxn 100005
#define mod 1000000007
using namespace std;
typedef long long ll;
ll da;
vector<pair<ll,ll> > mp[maxn];//存下图
bool vis[maxn];//标记曾经使用过的重心
ll maxsize[maxn],dis[maxn],d[maxn];//maxsize 当前节点的最大子树
ll siz[maxn],e[maxn];// dis 到重心的距离 d 出现过的距离
ll n,m,rt,sum,qe; // siz 当前节点的子树个数 e 出现的距离 rt代表当前重心
void find(ll x,ll f){//找出重心
siz[x]=;
maxsize[x]=;
for(int i=;i<mp[x].size();i++){
pair<ll,ll> q=mp[x][i];
if(q.first==f||vis[q.first]) continue;//vis数组标记曾经使用过的重心
find(q.first,x);
siz[x]+=siz[q.first];
maxsize[x]=max(maxsize[x],siz[q.first]);
}
maxsize[x]=max(maxsize[x],sum-siz[x]);//节点总数减去当前的子树数=以当前节点为根的父亲点子树数
if(maxsize[x]<maxsize[rt]){
rt=x;
}
}
void get_dis(ll x,ll f,ll len){
if(len<=1e7){
e[++qe]=len;
}
for(int i=;i<mp[x].size();i++){
pair<ll,ll> q=mp[x][i];
if(q.first==f||vis[q.first]) continue;
dis[q.first]=dis[x]+len;
get_dis(q.first,x,len+q.second);
}
}
ll solve(ll x,ll len){
ll ee=;
qe=;
dis[x]=len;
get_dis(x,,len);
sort(e+,e+qe+);
ll l=,r=qe;
while(l<r){
if(e[l]+e[r]<=m){
ee+=r-l;
l++;
}
else{
r--;
}
}
return ee;
}
void divide(ll x){
da+=solve(x,);
vis[x]=;
for(int i=;i<mp[x].size();i++){
pair<ll,ll> q=mp[x][i];
if(vis[q.first]) continue;
da-=solve(q.first,q.second);
sum=siz[q.first];
rt=;
maxsize[rt]=mod;
find(q.first,x);
divide(rt);
}
}
void init(){
da=;
for(int i=;i<=n;i++) mp[i].clear();
memset(maxsize,,sizeof(maxsize));
memset(vis,,sizeof(vis));
}
int main(){
while(cin>>n>>m)
{
if(n==&&m==) break;
ll a,b,c;
init();
for(int i=;i<n-;i++){
cin>>a>>b>>c;
a++;
b++;
mp[a].push_back(make_pair(b,c));
mp[b].push_back(make_pair(a,c));
}
sum=n;//当前节点数
rt=;
maxsize[]=mod;//置初值
find(,);
divide(rt);
printf("%lld\n",da);
}
}

最新文章

  1. 详解C#中的反射
  2. vim插件之tabular,代码对齐强迫症必备
  3. Hibernate总结(三)
  4. Drupal7网站+IIS7.0+PHP+MySql
  5. c++ *.h和*.cpp在编译中的作用
  6. WebForm 中的页面重定向和传值(转自 MSDN)
  7. CentOS安装中文输入法
  8. 开始使用storm
  9. Palindrome - URAL - 1297(求回文串)
  10. 当DOCKER遇上ESXI
  11. HDU 3516 Tree Construction (四边形不等式)
  12. 施用 maven shade plugin 解决 jar 或类的多版本冲突
  13. win10系统 L2TP连接尝试失败:ERROR因为安全层在初始化与远程计算机的协商时遇到了一个处理错误
  14. [LeetCode] Maximum Sum of 3 Non-Overlapping Subarrays 三个非重叠子数组的最大和
  15. 菜鸟玩云计算之廿一: saltstack之pillar
  16. 关于ARM CM3的启动文件分析
  17. 如果redis没有设置expire,他是否默认永不过期?
  18. MyEclipse中引用的maven配置文件只访问私服的配置
  19. Bow and Arrow Rigging in Blender
  20. Flex 数组问题!

热门文章

  1. Oracle系列:触发器、作业、序列、连接
  2. std::map使用结构体自定义键值
  3. 20190813 On Java8 第一章 对象的概念
  4. STP基本概念及实验
  5. 移动端web整理 移动端问题总结,移动web遇到的那些坑
  6. 56-python基础-python3-集合-新建集合
  7. hdu 1828 Picture(线段树轮廓线)
  8. python学习第二十九天函数局部变量如何改变外部变量
  9. NEO4J -模糊查询
  10. console.log的高级用法