【题意】给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000。注意点从0开始编号,无解输出-1。

【算法】点分治

【题解】每个区域按重心x划分子树,一条经过x的路径是从一个子树到另一个子树的(从x出发记为深度0即可),那么就让子树i的路径与子树1~i-1尝试合并,然后并入,这样就可以找到所有路径。

每个区域记录t[i]表示长度为i的路径最小边数,就可以过程中合并时计算答案ans = min{ ans , deep[x]+t[k-dis[x]] } 。

每个区域处理完要把t[]清空,然后再进入各个子区域。清空不能memset(否则复杂度不对),只能清空访问过的点。

复杂度O(n log n)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,maxk=;
int first[maxn],tot,sz[maxn],n,root,k,sum,dis[maxn],deep[maxn],ans,t[maxk],c[maxn],L,R;
bool vis[maxn];
struct edge{int v,w,from;}e[maxn*];
void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void getroot(int x,int fa){
sz[x]=;bool ok=;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v]){
getroot(e[i].v,x);
sz[x]+=sz[e[i].v];
if(sz[e[i].v]>sum/)ok=;
}
if(sum-sz[x]<=sum/&&ok)root=x;
}
void dfs(int x,int fa){
if(dis[x]>k)return;
ans=min(ans,deep[x]+t[k-dis[x]]);
c[++R]=x;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v]){
dis[e[i].v]=dis[x]+e[i].w;
deep[e[i].v]=deep[x]+;
dfs(e[i].v,x);
}
}
void solve(int x,int s){
vis[x]=;L=;R=;
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
deep[e[i].v]=;dis[e[i].v]=e[i].w;
dfs(e[i].v,x);
for(int j=L+;j<=R;j++)t[dis[c[j]]]=min(t[dis[c[j]]],deep[c[j]]);
L=R;
}
for(int i=;i<=R;i++)t[dis[c[i]]]=n;
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
if(sz[e[i].v]>sz[x])sum=s-sz[x];else sum=sz[e[i].v];
root=e[i].v;
getroot(e[i].v,x);
solve(root,sum);
}
}
int main(){
scanf("%d%d",&n,&k);
int u,v,w;
for(int i=;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
u++;v++;
insert(u,v,w);insert(v,u,w);
}
root=;sum=n;ans=n;
for(int i=;i<=k;i++)t[i]=n;
getroot(,);
solve(root,n);
if(ans==n)printf("-1");
else printf("%d",ans);
return ;
}

【BZOJ】2599: [IOI2011]Race 点分治的更多相关文章

  1. BZOJ 2599: [IOI2011]Race( 点分治 )

    数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...

  2. bzoj 2599: [IOI2011]Race (点分治 本地过了就是过了.jpg)

    题面:(复制别人的...) Description 给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的 ...

  3. bzoj 2599 [IOI2011]Race 点分

    [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 4768  Solved: 1393[Submit][Status][Dis ...

  4. bzoj 2599 [IOI2011]Race (点分治)

    [题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...

  5. BZOJ 2599 [IOI2011]Race【Tree,点分治】

    给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数. 点分治,这道题目和POJ 2114很接近,2114是 ...

  6. bzoj 2599: [IOI2011]Race【点分治】

    点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...

  7. 【刷题】BZOJ 2599 [IOI2011]Race

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

  8. BZOJ 2599: [IOI2011]Race

    点分治,定权值,求另一关键字最小 不满足前缀加减性 可以按序遍历,用一数组$t[] 来维护路径为i的最小边数$ 再对于一个直系儿子对应的子树,先算距离求答案再更新$t数组,这样就不会重复$ #incl ...

  9. 2599: [IOI2011]Race

    2599: [IOI2011]Race 链接 分析 被memset卡... 点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少.然后先遍历子树,更新答 ...

随机推荐

  1. 《DWZ笔记一》<select>动态联动菜单

    联动菜单,即组合框Combo box,在DWZ文档中对组合框combox的是这样描述的: 在传统的select 用class 定义:class=”combox”, html 扩展:保留原有属性name ...

  2. MySQL 基于mysqldump备份工具实战演练

    前言: 细节提示:先执行 show global variables like 'log_bin';看看log_bin的值,如果服务器变量log_bin的值为OFF,需要修改my.cnf配置文件,将l ...

  3. 3dContactPointAnnotationTool开发日志(二七)

      今天的主要工作是把选中物体以及复制删除物体和右边三个面板联系起来,就是通过鼠标框选住物体,右边面板的对应项的颜色也会改变,而且通过右边面板也能控制物体的选中状态,被选中的物体成cyan青色,并且包 ...

  4. 【BioCode】将多个蛋白质序列分成单个的txt文档

    代码说明: fasta格式的蛋白质序列,一个txt里面有很多蛋白质序列,计算ss.pssm或disorder score时候都需要单条计算,需要分开. 分割前: 分割后: show you the c ...

  5. ThinkPHP的调用css,js和图片的路径

    按网上的说法,在根目录下建了一个Public目录,把css,js和图片放到Public目录下,然后用__PUBLIC__/...或__ROOT__/Public/...调用.但是发现无论如何改路径都无 ...

  6. angularjs 指令间相互调用

    <div ng-app="app"> <div ng-controller="myctl"> <button superman s ...

  7. asp.net mvc4+EF 下使用UEditor

    一.从官方网站下载UEditor,http://ueditor.baidu.com/website/download.html, 我下载的是1.53.net版本

  8. 点击除指定元素以外的任意地方隐藏js

    $(document).click(function () { $(".search_box").hide(); }); $(".resultUl").on(& ...

  9. 【bzoj3518】点组计数 欧拉函数(欧拉反演)

    题目描述 平面上摆放着一个n*m的点阵(下图所示是一个3*4的点阵).Curimit想知道有多少三点组(a,b,c)满足以a,b,c三点共线.这里a,b,c是不同的3个点,其顺序无关紧要.(即(a,b ...

  10. 算法08 五大查找之:二叉排序树(BSTree)

    上一篇总结了索引查找,这一篇要总结的是二叉排序树(Binary Sort Tree),又称为二叉查找树(Binary Search Tree) ,即BSTree. 构造一棵二叉排序树的目的,其实并不是 ...