题目:https://vjudge.net/contest/307753#problem/B

题意:求树中路径和=k的点对是否存在

思路:点分治,这个题其实和上一题洛谷一样,只是这个数据强,我们不能直接预处理所有可能的路径长度,预处理所有路径长度复杂度 O(n^2) ,我们改为直接每次查询都分治一遍,我们只要把solve在O(n)求出来,那时间复杂度就是 O(n*logn*logn),时间上快了很多,其实等于k这个可以使用我们之前的方法。直接把不大于k的路径-小于k的路径=等于k的路径,然后搞一搞就可以了

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#define maxn 100005
#define mod 1e19
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){
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();
for(int i=;i<=n;i++) vis[i]=;
}
int main(){
while(scanf("%lld%lld",&n,&m)!=EOF)
{
if(n==&&m==) break;
ll a,b,c;
init();
char s[];
for(int i=;i<n-;i++){
scanf("%lld%lld%lld%s",&a,&b,&c,s);
//a++;
//b++;
mp[a].push_back(make_pair(b,c));
mp[b].push_back(make_pair(a,c));
}
scanf("%lld",&m);
sum=n;//当前节点数
rt=;
maxsize[]=mod;//置初值
find(,);
divide(rt);
printf("%lld\n",da);
}
}

POJ 2114 (点分治)的更多相关文章

  1. POJ 2114 点分治

    思路: 点分治 //By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> u ...

  2. poj 2114 Boatherds (树分治)

    链接:http://poj.org/problem?id=2114 题意: 求树上距离为k的点对数量: 思路: 点分治.. 实现代码: #include<iostream> #includ ...

  3. POJ 2114 Boatherds【Tree,点分治】

    求一棵树上是否存在路径长度为K的点对. POJ 1714求得是路径权值<=K的路径条数,这题只需要更改一下统计路径条数的函数即可,如果最终的路径条数大于零,则说明存在这样的路径. 刚开始我以为只 ...

  4. poj 2114 Boatherds 树的分治

    还是利用点的分治的办法来做,统计的办法不一样了,我的做法是排序并且标记每个点属于哪颗子树. #include <iostream> #include <cstdio> #inc ...

  5. Poj 2114 Boatherds(点分治)

    Boatherds Time Limit: 2000MS Memory Limit: 65536K Description Boatherds Inc. is a sailing company op ...

  6. 树分治 点分治poj 2114

    存在2点间距离==k 输出AYE 否则输出NAY #include<stdio.h> #include<string.h> #include<algorithm> ...

  7. POJ 2114 Boatherds 树分治

    Boatherds     Description Boatherds Inc. is a sailing company operating in the country of Trabantust ...

  8. poj 2114 树的分治 可作模板

    /* 啊啊啊啊啊啊啊本题证明一个问题,在实际应用中sort比qsort块 还有memset这类初始化能不加尽量别加,很浪费时间 原来的程序把qsort该成sort,去掉一个无用memset就a了时间不 ...

  9. POJ 2114 - Boatherds

    原题地址:http://poj.org/problem?id=2114 题目大意: 给定一棵点数为\(n~(n \le 10000)\)的无根树,路径上有权值,给出m组询问($m \le 100$), ...

随机推荐

  1. HTML--JS 表单验证

    <html> <head> <title>验证表单</title> <script type="text/javascript" ...

  2. poj1258Agri-Net(最小生成树)

    题目链接:http://poj.org/problem?id=1258 Description Farmer John has been elected mayor of his town! One ...

  3. C#后台去除字符串最后一个字符

    string str = "a,b,c,"; int length = str.length; //获取字符串长度 str = str.substring(0,length-1); ...

  4. 08 (h5*) js第9天--原型、继承

    目录: 1:原型和原型链 2:构造函数的原型可以改变 3:原型的最终指向 4:先修改原型指向,在添加方法. 5:实例对象中的属性和原型属性重合, 6:一个神奇的原型链 7:继承 8:原型链 9:利用c ...

  5. java创建线程的两种方式及源码解析

    创建线程的方式有很多种,下面我们就最基本的两种方式进行说明.主要先介绍使用方式,再从源码角度进行解析. 继承Thread类的方式 实现Runnable接口的方式 这两种方式是最基本的创建线程的方式,其 ...

  6. shell 删除项目日志

    删除半年之前的日志 find 后面紧跟目录 .为当前目录 -type f 指定查找的是文件 -mtime +180  查找180天之前的 -name  文件名筛选 -exec -rm -rf  执行的 ...

  7. nodejs启动

    npm install cnpm install npm run dev cnpm install 与 npm install :  https://blog.csdn.net/meng_suiga/ ...

  8. java_第一年_JavaWeb(4)

    HttpServletResponse对象 向客户端发送数据的方法: 通过getOutputStream()方法得到OutputStream对象,再通过write发送 通过getWriter()方法得 ...

  9. python学习第十一天列表的分片和运算

    列表的分片也叫切片,也就是从列表中取出一段赋值给另外一个变量,列表运算就是可以进行比较运算,连接运算,乘法运算等. 1,列表的分片 n1=[1,2,3,4,5,6,7,8,9] n2=[1:3] 包含 ...

  10. 使用定时器实现在console中打印内容

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...