【BZOJ2599】Race(点分治)

题面

BZOJ权限题,洛谷

题解

好久没写过点分治了。。。

在ppl的帮助下终于想起来了

orz ppl

首先回忆一下怎么求有没有正好是\(K\)的路径

维护一个表示距离的桶

对于当前重心,依次插入每棵子树的距离值

然后检查是否存在即可

显然加一步,求最短的路径数

那么,把原来的是否存在的01数组

改为记录最短路径数的一个\(int\)数组

每次插入的时候去取\(min\)就行了

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 220000
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next,w;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
int size[MAX],Size,K,n,dep[MAX],dis[MAX],ans;
bool vis[MAX];
int mx,root;
int ext[12000000];
int S[MAX],top;
int SS[MAX],Top;
void Getroot(int u,int ff)
{
size[u]=1;
int ret=0;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff||vis[v])continue;
Getroot(v,u);
ret=max(ret,size[v]);
size[u]+=size[v];
}
ret=max(Size-size[u],ret);
if(ret<mx)mx=ret,root=u;
}
void Getdep(int u,int ff,int ss,int st)
{
if(ss>K)return;
SS[++Top]=S[++top]=u;
dep[u]=ss;dis[u]=st;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(v==ff||vis[v])continue;
Getdep(v,u,ss+e[i].w,st+1);
}
}
void Calc(int u,int ff,int W)
{
top=0;Getdep(u,ff,W,1);
for(int i=1;i<=top;++i)
{
int dd=dep[S[i]];
if(!ext[K-dd])continue;
ans=min(ans,dis[S[i]]+ext[K-dd]);
}
for(int i=1;i<=top;++i)
{
int dd=dep[S[i]];
if(!ext[dd])ext[dd]=dis[S[i]];
else ext[dd]=min(ext[dd],dis[S[i]]);
}
}
void Work(int u)
{
vis[u]=true;Top=0;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
Calc(v,u,e[i].w);
}
if(ext[K])ans=min(ans,ext[K]);
for(int i=1;i<=Top;++i)ext[dep[SS[i]]]=0;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;
if(vis[v])continue;
Size=size[v],mx=n;
Getroot(v,u);
Work(root);
}
}
int main()
{
n=read();K=read();
for(int i=1;i<n;++i)
{
int u=read()+1,v=read()+1,w=read();
Add(u,v,w);Add(v,u,w);
}
Size=mx=n;Getroot(1,0);
ans=1e9;
Work(root);
printf("%d\n",ans==1e9?-1:ans);
return 0;
}

【BZOJ2599】Race(点分治)的更多相关文章

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

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

  2. 【BZOJ-2599】Race 点分治

    2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 2590  Solved: 769[Submit][Status ...

  3. [BZOJ2599][Race][IOI2011]点分治

    这是为了真正去学一下点分治..然后看了迪克李的ppt 又是一道写(改)了很久的题..终于ac了 1354799 orzliyicheng 2599 Accepted 31936 kb 23584 ms ...

  4. bzoj2599/luogu4149 [IOI2011]Race (点分治)

    点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...

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

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

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

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

  7. [IOI2011]Race 点分治

    [IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...

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

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

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

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

  10. [BZOJ2599]Race

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

随机推荐

  1. LeetCode - 520. Detect Capital

    Given a word, you need to judge whether the usage of capitals in it is right or not. We define the u ...

  2. 购物车【JavaWeb小项目、简单版】

    前言 为了巩固MVC的开发模式,下面就写一个购物车的小案例.. ①构建开发环境 导入需要用到的开发包 建立程序开发包 ②设计实体 书籍实体 public class Book { private St ...

  3. 使用supervisor 进行进程管理时调整最大文件打开数

    [supervisord]logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.loglogfile_maxbytes=50MB ; 日志文 ...

  4. MySQL的BlackHole引擎在主从架构中的作用

    MySQL在5.x系列提供了Blackhole引擎–“黑洞”. 其作用正如其名字一样:任何写入到此引擎的数据均会被丢弃掉, 不做实际存储:Select语句的内容永远是空. 和Linux中的 /dev/ ...

  5. Egret学习笔记 (Egret打飞机-3.实现背景循环滚动)

    游戏背景里面的猪脚飞机看起来是一直在向前飞,但是实际上只是一个视觉差而已. 猪脚是出于不动的状态,背景从上到下滚动,然后让玩家觉得飞机在不停的往前飞.(当然这只是其中一种实现思路) 差不多就是这样,然 ...

  6. hihoCoder1330 数组重排

    题意 小Hi想知道,如果他每次都按照一种固定的顺序重排数组,那么最少经过几次重排之后数组会恢复初始的顺序? 具体来讲,给定一个1 - N 的排列 P,小Hi每次重排都是把第 i 个元素放到第 Pi个位 ...

  7. Docker资源网站收藏

    Docker资源 Docker官方英文资源: docker官网:http://www.docker.com Docker windows入门:https://docs.docker.com/windo ...

  8. 遇到502错误,invalid request block size 解决方法

    uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 因为业务需求,要最多输入350个汉字,在 ...

  9. 利用Apache配置本地 自定义域名

    第一步:配置 httpd.conf 开启 虚拟主机 配置模块 去掉 " Include conf/extra/httpd-vhosts.conf " 前面的" # &qu ...

  10. SELinux一键开启与禁用脚本

    SELinux是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统.但是SELinux的并不能与众多服务很好的兼容,有些人会关闭SELinux一了百了.在日常的运 ...