【BZOJ2599】Race(点分治)
【BZOJ2599】Race(点分治)
题面
题解
好久没写过点分治了。。。
在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(点分治)的更多相关文章
- [bzoj2599][IOI2011]Race——点分治
Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...
- 【BZOJ-2599】Race 点分治
2599: [IOI2011]Race Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 2590 Solved: 769[Submit][Status ...
- [BZOJ2599][Race][IOI2011]点分治
这是为了真正去学一下点分治..然后看了迪克李的ppt 又是一道写(改)了很久的题..终于ac了 1354799 orzliyicheng 2599 Accepted 31936 kb 23584 ms ...
- bzoj2599/luogu4149 [IOI2011]Race (点分治)
点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...
- BZOJ2599:[IOI2011]Race(点分治)
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- [IOI2011]Race 点分治
[IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...
- 【BZOJ 2599】【IOI 2011】Race 点分治
裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...
- 【BZOJ】2599: [IOI2011]Race 点分治
[题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...
- [BZOJ2599]Race
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
随机推荐
- 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 ...
- 购物车【JavaWeb小项目、简单版】
前言 为了巩固MVC的开发模式,下面就写一个购物车的小案例.. ①构建开发环境 导入需要用到的开发包 建立程序开发包 ②设计实体 书籍实体 public class Book { private St ...
- 使用supervisor 进行进程管理时调整最大文件打开数
[supervisord]logfile=/tmp/supervisord.log ; 日志文件,默认是 $CWD/supervisord.loglogfile_maxbytes=50MB ; 日志文 ...
- MySQL的BlackHole引擎在主从架构中的作用
MySQL在5.x系列提供了Blackhole引擎–“黑洞”. 其作用正如其名字一样:任何写入到此引擎的数据均会被丢弃掉, 不做实际存储:Select语句的内容永远是空. 和Linux中的 /dev/ ...
- Egret学习笔记 (Egret打飞机-3.实现背景循环滚动)
游戏背景里面的猪脚飞机看起来是一直在向前飞,但是实际上只是一个视觉差而已. 猪脚是出于不动的状态,背景从上到下滚动,然后让玩家觉得飞机在不停的往前飞.(当然这只是其中一种实现思路) 差不多就是这样,然 ...
- hihoCoder1330 数组重排
题意 小Hi想知道,如果他每次都按照一种固定的顺序重排数组,那么最少经过几次重排之后数组会恢复初始的顺序? 具体来讲,给定一个1 - N 的排列 P,小Hi每次重排都是把第 i 个元素放到第 Pi个位 ...
- Docker资源网站收藏
Docker资源 Docker官方英文资源: docker官网:http://www.docker.com Docker windows入门:https://docs.docker.com/windo ...
- 遇到502错误,invalid request block size 解决方法
uWSGI是一个Web服务器,它实现了WSGI协议.uwsgi.http等协议.Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换. 因为业务需求,要最多输入350个汉字,在 ...
- 利用Apache配置本地 自定义域名
第一步:配置 httpd.conf 开启 虚拟主机 配置模块 去掉 " Include conf/extra/httpd-vhosts.conf " 前面的" # &qu ...
- SELinux一键开启与禁用脚本
SELinux是美国国家安全局(NSA)对于强制访问控制的实现,是 Linux历史上最杰出的新安全子系统.但是SELinux的并不能与众多服务很好的兼容,有些人会关闭SELinux一了百了.在日常的运 ...