还是点对之间的问题,果断上点分治

同样,把一条路径拆分成经过根节点的两条路径,对不经过根节点的路径递归处理

然后,我们逐个枚举根节点的子树,计算出子树中某一点到根节点的距离,然后在之前已经处理过的点中找,看有没有距离之和等于k的,如果有就取最小值(这里用桶维护即可)

然后再把这个子树内的信息扔进桶里,计算下一棵子树即可

但是注意,在递归处理之前需要把桶清空!

然后就没啥了

不合法的情况就是无法更新出答案,输出-1即可

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const int inf=0x3f3f3f3f;
struct Edge
{
int next;
int to;
int val;
}edge[];
int head[];
int cnt=;
int n,k;
int s,rt;
int siz[];
int maxp[];
bool vis[];
int dep[];
int dis[];
int has[];
int ans=0x3f3f3f3f;
void init()
{
memset(head,-,sizeof(head));
cnt=;
}
void add(int l,int r,int w)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
head[l]=cnt++;
}
void get_rt(int x,int fa)
{
siz[x]=,maxp[x]=;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
get_rt(to,x);
siz[x]+=siz[to];
maxp[x]=max(maxp[x],siz[to]);
}
maxp[x]=max(maxp[x],s-siz[x]);
if(maxp[x]<maxp[rt])rt=x;
}
void calc(int x,int fa)
{
if(dis[x]<=k)ans=min(ans,dep[x]+has[k-dis[x]]);
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
dep[to]=dep[x]+,dis[to]=dis[x]+edge[i].val;
calc(to,x);
}
}
void update(int x,int fa)
{
if(dis[x]<=k)has[dis[x]]=min(has[dis[x]],dep[x]);
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
update(to,x);
}
}
void erase(int x,int fa)
{
if(dis[x]<=k)has[dis[x]]=inf;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fa||vis[to])continue;
erase(to,x);
}
}
void solve(int x)
{
vis[x]=,has[]=;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
dep[to]=,dis[to]=edge[i].val;
calc(to,);
update(to,);
}
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
erase(to,);
}
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])continue;
s=siz[to],rt=,maxp[rt]=inf;
get_rt(to,);
solve(rt);
}
}
int main()
{
scanf("%d%d",&n,&k);
init();
for(int i=;i<=k;i++)has[i]=n;
for(int i=;i<n;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
x++,y++;
add(x,y,z),add(y,x,z);
}
ans=maxp[rt]=s=n;
get_rt(,);
solve(rt);
ans=(ans==n)?-:ans;
printf("%d\n",ans);
return ;
}

bzoj 2599的更多相关文章

  1. BZOJ 2599 Race(树分治)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 题意:每次 ...

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

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

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

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

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

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

  5. bzoj 2599(点分治)

    2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 3642  Solved: 1081[Submit][Statu ...

  6. 【BZOJ 2599】【IOI 2011】Race 点分治

    裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...

  7. bzoj 2599 数分治 点剖分

    具体可以见漆子超的论文 /**************************************************************     Problem:     User: B ...

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

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

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

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

随机推荐

  1. 使用elementUI滚动条之横向滚动

    用过elementUI组件应该会知道它内置一个滚动效果,官网对此组件没有相关文档,也是细心网友发现的. <el-scrollbar></el-scrollbar> 将会出现滚动 ...

  2. C++中typedef enum 和 enum

    在C++中,这两种定义枚举类型的关键字用法和效果相同,推荐使用前者.typedef enum多用在C语言中. 在C语言中,如果使用typedef enum定义一个枚举类型,比如: typedef en ...

  3. GraphQL

    GraphQL 官方描述: GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时. GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地 ...

  4. Vue(小案例_vue+axios仿手机app)_购物车(计算商品总金额)

    一.前言                 1.计算总金额                 2.点击删除按钮,删除对应的商品信息                 3.当还没结算的时候,当用户跳到其他页面 ...

  5. 标签传播算法(Label Propagation Algorithm, LPA)初探

    0. 社区划分简介 0x1:非重叠社区划分方法 在一个网络里面,每一个样本只能是属于一个社区的,那么这样的问题就称为非重叠社区划分. 在非重叠社区划分算法里面,有很多的方法: 1. 基于模块度优化的社 ...

  6. Java IO系列之一:IO

    1. 概述 Java IO一般包含两个部分: 1.java.io包中堵塞型IO: 2.java.nio包中的非堵塞型IO,通常称为New IO. java.io包下,分为四大块近80个类: 1.基于字 ...

  7. JS中如何获取JSON有多少个字段,JSON子项的个数或叫length

    如有JSON数据格式如下: {names:'张三','age':16,'sex':‘男’} 或 {names:'张三','age':16,'sex':‘男’} 如何获取JSON子键的数量?挺头疼的.使 ...

  8. mix-blend-mode

    mix-blend-mode是一个css3新增的混合color与背景元素颜色的样式,同一个元素的两个颜色不影响. mix-blend-mode: normal;          //正常mix-bl ...

  9. Java SE之快速失败(Fast-Fail)与快速安全(Fast-Safe)的区别[集合与多线程/增强For](彻底详解)

    声明 特点:基于JDK源码进行分析. 研究费时费力,如需转载或摘要,请显著处注明出处,以尊重劳动研究成果:博客园 - https://www.cnblogs.com/johnnyzen/p/10547 ...

  10. C# MVC分页简单介绍

    ASP.NET MVC中进行分页的方式有多种,这里介绍一种简单实用的方法 一:在实现分页之前,先添加“PagedList”和“PagedList.Mvc”两个组件,具体下载直接在NuGet程序包里收索 ...