题目:https://www.luogu.org/problemnew/show/P4178

这道题要把 dep( dis? ) 加入一个 tmp 数组里,排序,计算点对,复杂度很美;

没有写 sort 竟然还有50分!

虽然调了很久不过第一次用对拍找出了错误!

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=,inf=0x3f3f3f3f;
int n,hd[maxn],ct,to[maxn<<],nxt[maxn<<],w[maxn<<],tmp[maxn],l,r;
int sum,siz[maxn],dep[maxn],mx,rt;
ll ans,K;
bool vis[maxn];
void add(int x,int y,int z){to[++ct]=y; nxt[ct]=hd[x]; w[ct]=z; hd[x]=ct;}
void getrt(int x,int fa)
{
siz[x]=; int nmx=;
for(int i=hd[x],u;i;i=nxt[i])
{
if(to[i]==fa||vis[to[i]])continue;
getrt(u=to[i],x);
siz[x]+=siz[u]; nmx=max(nmx,siz[u]);
}
nmx=max(nmx,sum-siz[x]);
if(nmx<mx)mx=nmx,rt=x;
}
void getdep(int x,int fa)
{
tmp[++r]=dep[x];
for(int i=hd[x];i;i=nxt[i])
{
if(to[i]==fa||vis[to[i]])continue;
dep[to[i]]=dep[x]+w[i];
getdep(to[i],x);
}
}
ll calc(int x,int w)
{
dep[x]=w; r=; getdep(x,);
l=; ll ret=;
sort(tmp+l,tmp+r+);//!!!
while(l<=r)
{
if(tmp[l]+tmp[r]<=K)ret+=r-l,l++;//l -> l+1,l+2,...,r
else r--;
}
return ret;
}
void work(int x)
{
ans+=calc(x,); vis[x]=;
for(int i=hd[x];i;i=nxt[i])
{
if(vis[to[i]])continue;
ans-=calc(to[i],w[i]);
sum=siz[to[i]]; mx=inf;
// getrt(to[i],x);
getrt(to[i],);
work(rt);
}
}
int main()
{
scanf("%d",&n);
for(int i=,x,y,w;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
add(x,y,w); add(y,x,w);
}
scanf("%lld",&K);
sum=n; mx=inf; getrt(,);
work(rt);
printf("%lld\n",ans);
return ;
}

洛谷 P4178 Tree —— 点分治的更多相关文章

  1. 洛谷P4178 Tree (点分治)

    题目描述 给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K 输入输出格式 输入格式:   N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下 ...

  2. [洛谷P4178] Tree (点分治模板)

    题目略了吧,就是一棵树上有多少个点对之间的距离 \(\leq k\) \(n \leq 40000\) 算法 首先有一个 \(O(n^2)\) 的做法,枚举每一个点为起点,\(dfs\) 一遍可知其它 ...

  3. POJ1471 Tree/洛谷P4178 Tree

    Tree P4178 Tree 点分治板子. 点分治就是直接找树的重心进行暴力计算,每次树的深度不会超过子树深度的\(\frac{1}{2}\),计算完就消除影响,找下一个重心. 所以伪代码: voi ...

  4. 点分治模板(洛谷P4178 Tree)(树分治,树的重心,容斥原理)

    推荐YCB的总结 推荐你谷ysn等巨佬的详细题解 大致流程-- dfs求出当前树的重心 对当前树内经过重心的路径统计答案(一条路径由两条由重心到其它点的子路径合并而成) 容斥减去不合法情况(两条子路径 ...

  5. 2018.07.20 洛谷P4178 Tree(点分治)

    传送门 又一道点分治. 直接维护子树内到根的所有路径长度,然后排序+双指针统计答案. 代码如下: #include<bits/stdc++.h> #define N 40005 using ...

  6. 洛谷 4178 Tree——点分治

    题目:https://www.luogu.org/problemnew/show/P4178 点分治.如果把每次的 dis 和 K-dis 都离散化,用树状数组找,是O(n*logn*logn),会T ...

  7. 洛谷P4178 Tree (算竞进阶习题)

    点分治 还是一道点分治,和前面那道题不同的是求所有距离小于等于k的点对. 如果只是等于k,我们可以把重心的每个子树分开处理,统计之后再合并,这样可以避免答案重复(也就是再同一个子树中出现路径之和为k的 ...

  8. [洛谷P4178]Tree

    题目大意:给一棵树,问有多少条路径长度小于等于$k$ 题解:点分治 卡点:无 C++ Code: #include <cstdio> #include <algorithm> ...

  9. 洛谷 P4178 Tree

    #include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #inclu ...

随机推荐

  1. css去掉div的滚动条

    懒得讲原理了,直接贴代码: css部分: .slide-box { margin-top: 200px; display: -webkit-box; overflow-x: scroll; overf ...

  2. Tensorflow学习笔记(1):tf.slice()函数使用

    tensorflow 当中的一个常用函数:Slice() def slice(input_, begin, size, name=None) 函数的功能是根据begin和size指定获取input的部 ...

  3. Linux学习笔记记录(九)

  4. 深入理解PHP之strpos

    概述 在php中经常用 strpos 判断字符串是否在另一个字符串中存在, 本文介绍 strpos 函数及其实现. strpos应用 <?php /* strpos示例 */ // test e ...

  5. STM32单片机串口一键下载电路与操作方法详解

    STM32三种启动模式对应的存储介质均是芯片内置的,它们是:1)用户闪存 = 芯片内置的Flash.2)SRAM = 芯片内置的RAM区,就是内存啦.3)系统存储器 = 芯片内部一块特定的区域,芯片出 ...

  6. Spring整合Junit框架

    一.开发环境 eclipse版本:4.6.1 maven版本:3.3.3 junit版本:4.12 spring版本:4.1.5.RELEASE JDK版本:1.8.0_111 二.项目结构 图 三. ...

  7. 手写DAO框架(三)-数据库连接

    -------前篇:手写DAO框架(二)-开发前的最后准备--------- 前言 上一篇主要是温习了一下基础知识,然后将整个项目按照模块进行了划分.因为是个人项目,一个人开发,本人采用了自底向上的开 ...

  8. 最小生成树 B - Networking

    You are assigned to design network connections between certain points in a wide area. You are given ...

  9. jd-eclipse插件的安装

    一,资源 jd-eclipse-site-1.0.0-RC2.zip    百度网盘链接:https://pan.baidu.com/s/1GTFFY_1jg4k9vjZNE4JliQ       提 ...

  10. HDU 4005 The war(双连通好题)

    HDU 4005 The war pid=4005" target="_blank" style="">题目链接 题意:给一个连通的无向图.每条 ...