【BZOJ2599】[IOI2011]Race

Description

给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000

Input

第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3
0 1 1
1 2 2
1 3 4

Sample Output

2

题解:本题大部分代码都与POJ1741那道模板题相同,只不过是calc函数里有些不一样

如果我们想计算一棵子树里的答案,仍然是先按照每个点到根的距离排序,然后用双指针法算出长度=m的路径,那么问题来了,我们怎样将答案中的非简单路径去掉呢?

由于我们最终要求的是经过边最少的长度=m的简单路径,那么我们可以用ans[i]保存经过i条边的路径数,然后在calc的时候直接修改ans就行了

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=200010;
int to[maxn<<1],next[maxn<<1],val[maxn<<1],dep[maxn],s[maxn],head[maxn],siz[maxn];
int vis[maxn],ans[maxn],p[maxn];
int n,m,tot,cnt,root,maxx; bool cmp(int a,int b)
{
return s[a]<s[b];
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
void getroot(int x,int fa)
{
int i,mx=0;
siz[x]=1;
for(i=head[x];i!=-1;i=next[i])
{
if(to[i]==fa||vis[to[i]]) continue;
getroot(to[i],x);
siz[x]+=siz[to[i]];
mx=max(mx,siz[to[i]]);
}
mx=max(mx,tot-siz[x]);
if(maxx>mx) root=x,maxx=mx;
}
void getdep(int x,int fa)
{
p[++p[0]]=x;
for(int i=head[x];i!=-1;i=next[i])
{
if(to[i]==fa||vis[to[i]]) continue;
s[to[i]]=s[x]+val[i],dep[to[i]]=dep[x]+1;
getdep(to[i],x);
}
}
void calc(int x,int flag)
{
p[0]=0,getdep(x,0);
sort(p+1,p+p[0]+1,cmp);
int l=1,r=p[0],i;
for(;l<r;l++)
{
while(l<r&&s[p[l]]+s[p[r]]>m) r--;
for(i=r;i>l&&s[p[l]]+s[p[i]]==m;i--) ans[dep[p[l]]+dep[p[i]]]+=flag;
}
}
void dfs(int x)
{
vis[x]=1;
s[x]=dep[x]=0,calc(x,1);
for(int i=head[x];i!=-1;i=next[i])
{
if(vis[to[i]]) continue;
s[to[i]]=val[i],dep[to[i]]=1,calc(to[i],-1);
maxx=1<<30,tot=siz[to[i]],getroot(to[i],x);
dfs(root);
}
}
int main()
{
scanf("%d%d",&n,&m);
int i,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++)
{
scanf("%d%d%d",&a,&b,&c),a++,b++;
add(a,b,c),add(b,a,c);
}
maxx=1<<30;
getroot(1,0);
dfs(1);
for(i=1;i<=n;i++)
{
if(ans[i])
{
printf("%d\n",i);
return 0;
}
}
printf("-1");
return 0;
}

【BZOJ2599】[IOI2011]Race 树的点分治的更多相关文章

  1. [bzoj2599][IOI2011]Race——点分治

    Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...

  2. [luogu4149][bzoj2599][IOI2011]Race【点分治】

    题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...

  3. 2019.01.09 bzoj2599: [IOI2011]Race(点分治)

    传送门 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 思路: 考虑点分治如何合并. 我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可. 代码: ...

  4. BZOJ2599 [IOI2011]Race 【点分治】

    题目 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 输入格式 第一行 两个整数 n, k 第二..n行 每行三个整 ...

  5. bzoj2599: [IOI2011]Race(点分治)

    写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...

  6. BZOJ2599:[IOI2011]Race(点分治)

    Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...

  7. 【点分治】【哈希表】bzoj2599 [IOI2011]Race

    给nlog2n随便过的跪了,不得已弄了个哈希表伪装成nlogn(当然随便卡,好孩子不要学)…… 不过为啥哈希表的大小开小点就RE啊……?必须得超过数据范围一大截才行……谜 #include<cs ...

  8. bzoj1758 [Wc2010]重建计划 & bzoj2599 [IOI2011]Race

    两题都是树分治. 1758这题可以二分答案avgvalue,因为avgvalue=Σv(e)/s,因此二分后只需要判断Σv(e)-s*avgvalue是否大于等于0,若大于等于0则调整二分下界,否则调 ...

  9. BZOJ2599——[IOI2011]Race

    0.题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 1.分析:水题一道,一波树分治就好 我们可以发现这个题的K是比较小的,才100w,那么我们可以树分治一下,在遍历每一棵子树的 ...

随机推荐

  1. js本地图片预览,兼容ie[6-9]、火狐、Chrome17+、Opera11+、Maxthon3

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. 透明遮罩图层VS高斯模糊滤镜 效果分析

    前端流行布局中最常见的弹出图层有popup, 对话框, tooltip等, 他们都使用了新的图层,但是实现办法各不相同, 有 的是通过半通明的黑白图层实现的, 有的是通过滤镜实现的, 我们来研究一下两 ...

  3. WebForm和MVC的一些知识(转)

    转自:http://www.cnblogs.com/liuhf939/p/3417203.html 比较WebForm和Mvc的请求处理方式 首先简单了解一下Asp.Net中怎么对页面进行请求处理的: ...

  4. Hash表的表大小

    hash表的出现主要是为了对内存中数据的快速.随机的访问.它主要有三个关键点:Hash表的大小.Hash函数.冲突的解决. 这里首先谈谈第一点:Hash表的大小. Hash表的大小一般是定长的,如果太 ...

  5. am335x i2c分析

    /***************************************************************************** * am335x i2c分析 * i2c驱 ...

  6. ffplay(2.0.1)中的音视频同步

    最近在看ffmpeg相关的一些东西,以及一些播放器相关资料和代码. 然后对于ffmpeg-2.0.1版本下的ffplay进行了大概的代码阅读,其中这里把里面的音视频同步,按个人的理解,暂时在这里作个笔 ...

  7. 鼠标捕获(setCapture,releaseCapture)的学习

    鼠标捕获(setCapture)作用是将鼠标事件捕获到当前文档的指定的对象——对指定的对象设置鼠标捕获.这个对象会为当前应用程序或整个系统接收所有鼠标事件. 所谓鼠标捕获,是指对鼠标事件(onmous ...

  8. Java 基本概念:jvm、jdk、jre、jse

    jvm 是java虚拟机,将java的class字节码文件翻译成二进制可执行程序.jdk 是java的开发包 Javasdk, java的开发工具,包含SUN公司提供的javaAPI,将java源码编 ...

  9. js中onclick中文参数传输方式

    添加单引号或双引号即可,例: var type = "'"+n.bankCard.type+"'"; var number = "'"+n. ...

  10. jQuery-替换和删除元素

    1.replaceWith方法 用提供的内容替换集合中所有匹配的元素并且返回被替换元素的集合 参数类型说明: 1)普通字符串(可包含各种html标签) 2)jQuery对象 ①使用$函数创建的新元素( ...