题目描述

给出一棵树,求出最小的k,使得,且在树中存在路径p,使得k>=S且k<=E。(k为路径p上的边的权值和)

输入

第一行给出N,S,E。N代表树的点数,S,E如题目描述。

下面N-1行给出这棵树的相邻两个节点的边及其权值W。

输出

输出共一行一个整数,表示答案。若无解输出-1。

样例输入

5 10 40

2 4 80

2 3 57

1 2 16

2 5 49

样例输出

16

样例解释

1到2的路径即为答案。

数据范围

对于20%的数据满足n<=300

对于50%的数据满足n<=3000

对于60%的数据满足n<=10^5

对于以上数据,满足|E-S|<=50

对于100%的数据满足n<=10^5,|E-S|<=10^6

对于所有数据满足1<=Wi<=1000,|E|,|S|<=10^9

解法

树上路径问题使用树分治解决。

对于当前树,维护一个Dis数组表示,当前树中的每个点到当前树根结点的距离。

依次遍历当前根结点的子树,得出来一个dis表示这个子树的结点到当前根结点的距离。考虑合并Dis和dis,对于每个dis[i],在Dis中二分出一个Dis[j]使得Dis[j]+dis[i]>=S,然后更新答案。

最后把dis并入Dis维护有序性即可。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define sqr(x) ((x)*(x))
#define ln(x,y) int(log(x)/log(y))
using namespace std;
const char* fin="aP2.in";
const char* fout="aP2.out";
const int inf=0x7fffffff;
const int maxn=100007,maxm=2*maxn,maxde=31;
int n,m1,m2,i,j,k,l,tot,siz,root,ans=inf;
int fi[maxn],la[maxm],va[maxm],ne[maxm];
int dis[maxn],Dis[maxn];
bool bz[maxn];
void add_line(int a,int b,int c){
tot++;
ne[tot]=fi[a];
la[tot]=b;
va[tot]=c;
fi[a]=tot;
}
void getsize(int v,int from){
int i,j,k;
if (!from) siz=0;
siz++;
for (k=fi[v];k;k=ne[k]) if (!bz[la[k]] && la[k]!=from) getsize(la[k],v);
}
int getroot(int v,int from){
int i=1,j=1,k,tmp;
for (k=fi[v];k;k=ne[k]){
if (!bz[la[k]] && la[k]!=from) {
tmp=getroot(la[k],v);
if (tmp>siz/2) i=0;
j+=tmp;
}
}
if (i && j>siz/2) root=v;
return j;
}
void getdis(int v,int from,int st){
int i,j,k;
if (st>m2) return;
dis[++dis[0]]=st;
for (k=fi[v];k;k=ne[k]){
if (la[k]!=from && !bz[la[k]]){
getdis(la[k],v,st+va[k]);
}
}
}
void merge(){
int i,j,k,l,r,mid;
for (i=1;i<=dis[0];i++){
l=1;
r=Dis[0];
while (l<r){
mid=(l+r)/2;
if (dis[i]+Dis[mid]>=m1) r=mid;
else l=mid+1;
}
if (dis[i]+Dis[l]>=m1) ans=min(ans,dis[i]+Dis[l]);
}
for (i=1;i<=dis[0];i++) Dis[++Dis[0]]=dis[i];
sort(Dis+1,Dis+Dis[0]+1);
}
void dfs(int v,int de){
int i,j,k;
Dis[0]=1;
Dis[1]=0;
bz[v]=true;
for (k=fi[v];k;k=ne[k]){
if (!bz[la[k]]){
dis[0]=0;
getdis(la[k],v,va[k]);
merge();
}
}
for (k=fi[v];k;k=ne[k])
if (!bz[la[k]]){
getsize(la[k],0);
getroot(la[k],0);
dfs(la[k],de+1);
}
}
int main(){
scanf("%d%d%d",&n,&m1,&m2);
for (i=1;i<n;i++){
scanf("%d%d%d",&j,&k,&l);
add_line(j,k,l);
add_line(k,j,l);
}
getsize(1,0);
getroot(1,0);
dfs(1,0);
if (ans>m2) printf("-1");
else printf("%d",ans);
return 0;
}

启发

树上路径问题使用树上分治。

树上分治处理方法并不单一,须灵活运用。

【JZOJ4715】【NOIP2016提高A组模拟8.19】树上路径的更多相关文章

  1. [jzoj 4668] [NOIP2016提高A组模拟7.19] 腐败 解题报告(质数分类+慢速乘)

    题目链接: http://172.16.0.132/senior/#main/show/4668 题目: 题解: 考虑把A数组里的每个元素分解质因数,对于每个质因数开一个vector存一下包含这个质因 ...

  2. 【NOIP2016提高A组模拟8.19】(雅礼联考day2)总结

    第一题又有gcd,又有xor,本来想直接弃疗,不过后来想到了个水法: 当两个相邻的数满足条件时,那么他们的倍数也可能满足条件.然后没打,只打了个暴力. 正解就是各种结论,各种定理搞搞. 第二题,想都不 ...

  3. 【NOIP2016提高A组模拟8.19】(雅礼联考day2)公约数

    题目 给定一个正整数,在[1,n]的范围内,求出有多少个无序数对(a,b)满足gcd(a,b)=a xor b. 分析 显然a=b是一定不满足, 我们设\(a>b\), 易得gcd(a,b)&l ...

  4. 【NOIP2016提高A组模拟8.19】(雅礼联考day2)树上路径

    题目 给出一棵树,求出最小的k,使得,且在树中存在路径p,使得k>=S且k<=E.(k为路径p上的边的权值和). 分析 点分治,设当前为x的,求在以x为根的子树中,经过x的路径(包括起点或 ...

  5. JZOJ 4732. 【NOIP2016提高A组模拟8.23】函数

    4732. [NOIP2016提高A组模拟8.23]函数 (Standard IO) Time Limits: 1500 ms  Memory Limits: 262144 KB  Detailed ...

  6. 【NOIP2016提高A组模拟9.14】数列编辑器

    题目 分析 比赛上,没有注意到询问只询问光标前面,于是只打了个暴力. 因为询问只询问光标前面,首先,当光标向后每移动到一个位置,顺便将这个位置的前缀和,和最大前缀和求出来. 总之,模拟 #includ ...

  7. 【NOIP2016提高A组模拟9.24】总结

    第一题纯模拟,结果那个出题人脑子似乎进水了,空间限制开了1G!!! 导致我捉摸了半天为什么空间要开那么大,最后只能得出上面的结论. 第二题是个矩阵快速幂,比赛上我没把递推式求出来,但是根据各种乱搞,得 ...

  8. 【NOIP2016提高A组模拟9.24】我的快乐时代

    题目 分析 虽然我们很难求出\(\sum_{i=n}^mjoy(i)\), 但是我们可以分别求出\(\sum_{i=1}^mjoy(i)\)和\(\sum_{i=1}^{n-1}joy(i)\),相减 ...

  9. 【JZOJ4711】【NOIP2016提高A组模拟8.17】Binary

    题目描述 输入 输出 样例输入 6 6 8 9 1 13 9 3 1 4 5 2 6 9 1 3 7 2 7 7 1 6 1 2 11 13 样例输出 45 19 21 数据范围 解法 40%暴力即可 ...

随机推荐

  1. node概览和安装

    一.node是一个平台环境,可以运行js代码的服务器端平台. 设计最初node是用来解决并发问题的,现在可以用来放在服务端使用. node平台的有优点:运行速度快,支持高并发,轻便.小巧 但是与jav ...

  2. LA4794 Sharing Chocolate

    传送门 记忆化搜索. 在下觉得sxy大佬的代码写得相当好,通篇的骚操作(因为我都不会呀),%%% 学到了 预处理每个状态的值.以前的我都是zz地枚举每一位.. for(int i=1;i<(1& ...

  3. leyou_03_cors解决ajax的跨域请求问题

    1.为什么会有跨域问题 因为跨域问题是浏览器对于ajax请求的一种安全限制:一个页面发起的ajax请求,只能是与当前页域名相同的路径,这能有效的阻止跨站攻击. 因此:跨域问题 是针对ajax的一种限制 ...

  4. EPSG、SRID、WKT的概念

    转自:http://www.cnblogs.com/jackdong/archive/2010/12/20/1911558.html EPSG:European Petroleum Survey Gr ...

  5. 玩转python爬虫之正则表达式

    玩转python爬虫之正则表达式 这篇文章主要介绍了python爬虫的正则表达式,正则表达式在Python爬虫是必不可少的神兵利器,本文整理了Python中的正则表达式的相关内容,感兴趣的小伙伴们可以 ...

  6. xshell 连接 kali

    1   修改配置文件 vi /etc/ssh/sshd_config #PasswordAuthentication no 去掉#,并且将no修改为YES //kali中默认是yes PermitRo ...

  7. IDEA中配置国内maven库镜像(阿里云)

    配置maven中settings.xml,在mirrors段内增加镜像配置,配置后如下: <mirror> <id>nexus-aliyun</id> <mi ...

  8. python 中文乱码问

    在本文中,以'哈'来解释作示例解释所有的问题,“哈”的各种编码如下: 1. UNICODE (UTF8-16),C854: 2. UTF-8,E59388: 3. GBK,B9FE. 一.python ...

  9. JAVA面试常见问题之数据库篇

    1.MySQL 索引使用的注意事项 更新频繁的列不要加索引 数据量小的表不要加索引 重复数据多的字段不要加索引,比如性别字段 首先应该考虑对where 和 order by 涉及的列上建立索引 2.D ...

  10. win10系统下安装打印机驱动

    以前安装过一次打印机的驱动,当时是从网上下载的,今天按照以前的方法安装打印机驱动,发现并不能使用,而且并不知道驱动还能自动安装. 首先在系统图标下选择设置-设备和打印机-添加打印机-搜索打印机,如果没 ...