【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 第二 ...
随机推荐
- 读书共享 Primer Plus C-part11
第十四章结构和其他数据形式 关于fread以及fwrite fread(char* buff,int size,int count,FILE* fp) fwrite(char* buff,int si ...
- ChineseUtils
这里获得汉字的拼音使用了pinyin4j这个插件,因为多音字的原因效果并不理想 /** * 获得汉字拼音 * @param name * @return */ @SuppressWarnings(&q ...
- ThinkPHP的使用
在public目录下使用命令行执行:php -S localhost:8888 route.php 无需使用服务器就可启动
- 【NOIP2015】字串
[NOIP2015]字串 标签: DP NOIP Description 有两个仅包含小写英文字母的字符串 A 和 B.现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其 ...
- 【Unity3D技术文档翻译】第1.4篇 AssetBundle 依赖关系
上一章:[Unity3D技术文档翻译]第1.3篇 创建 AssetBundles 本章原文所在章节:[Unity Manual]→[Working in Unity]→[Advanced Develo ...
- redux middleware 源码分析
原文链接 middleware 的由来 在业务中需要打印每一个 action 信息来调试,又或者希望 dispatch 或 reducer 拥有异步请求的功能.面对这些场景时,一个个修改 dispat ...
- PHP 支持加解密的函数
function encrypt($string,$operation,$key=''){ $key=md5($key); $key_length=strlen($key); $string=$ope ...
- OpenCV 之 空间滤波
1 空间滤波 1.1 基本概念 空间域,在图像处理中,指的是像平面本身: 空间滤波,则是在像平面内,对像素值所进行的滤波处理. 如上图所示,假设点 (x, y) 为图像 f 中的任意点,中间正方形 ...
- Activity的生命周期& 启动模式
1.Activity的生命周期 生命周期这个事情,是android工程师最基础的知识,所以今天要讲的是一些不一样的东西. 1.1 OnStart,OnResume,OnPause,OnStop 他们的 ...
- java8在Collection中新增加的方法removeIf
记得我在以前找工作的经历中,遇到过一个面试官问过我一个很基础的问题.问题是:有一个List中有10个元素,我现在想从中删除3个元素,请问怎么做?我当时也没想,就直接说,List的有自带的remove方 ...