bzoj 2599
还是点对之间的问题,果断上点分治
同样,把一条路径拆分成经过根节点的两条路径,对不经过根节点的路径递归处理
然后,我们逐个枚举根节点的子树,计算出子树中某一点到根节点的距离,然后在之前已经处理过的点中找,看有没有距离之和等于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的更多相关文章
- BZOJ 2599 Race(树分治)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 题意:每次 ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- bzoj 2599: [IOI2011]Race (点分治 本地过了就是过了.jpg)
题面:(复制别人的...) Description 给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的 ...
- 【刷题】BZOJ 2599 [IOI2011]Race
Description 给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000 Input 第一行 两个整数 n, k 第二 ...
- bzoj 2599(点分治)
2599: [IOI2011]Race Time Limit: 70 Sec Memory Limit: 128 MBSubmit: 3642 Solved: 1081[Submit][Statu ...
- 【BZOJ 2599】【IOI 2011】Race 点分治
裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...
- bzoj 2599 数分治 点剖分
具体可以见漆子超的论文 /************************************************************** Problem: User: B ...
- bzoj 2599 [IOI2011]Race (点分治)
[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...
- BZOJ 2599 [IOI2011]Race【Tree,点分治】
给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数. 点分治,这道题目和POJ 2114很接近,2114是 ...
随机推荐
- 论Scrapy中的数据持久化
引入 Scrapy的数据持久化,主要包括存储到数据库.文件以及内置数据存储. 那我们今天就来讲讲如何把Scrapy中的数据存储到数据库和文件当中. 终端指令存储 保证爬虫文件的parse方法中有可迭代 ...
- 【XSY3370】道路建设 最短路
题目大意 有一个完全图,边有边权. 对于每个 \(i\),求一棵生成树,使得( \(\sum_{j=1,j\neq i}^n\) \(j\) 到 \(i\) 的路径上边权最小值) 最小. \(n\le ...
- Alice and Bob HDU - 4111 (SG函数)
Alice and Bob are very smart guys and they like to play all kinds of games in their spare time. The ...
- java 11 实现RFC7539中指定的ChaCha20和Poly1305两种加密算法, 代替RC4
实现 RFC 7539的ChaCha20 and ChaCha20-Poly1305加密算法 RFC7748定义的秘钥协商方案更高效, 更安全. JDK增加两个新的接口 XECPublicKey 和 ...
- python全栈开发中级班全程笔记(第二模块)第一部分:文件处理
第二模块 第一部分:文件处理与函数 #插曲之人丑就要多读书:读书能够提高个人素质与内涵,提升个人修养与能力,以及层次的提升. 推荐书籍:追风筝的人.白鹿原 电影:阿甘正传.辛德勒的名单 第一节:三 ...
- Unity安装(Windows版)
Unity下载助手 Unity下载助手是一个小型可执行程序(大小约为1 MB),它允许您选择要下载和安装的Unity Editor的那些组件. 如果你不知道要安装,保留默认选择,单击继续 ,然后按照安 ...
- python之路(9)反射、包装类、动态模块导入
目录 反射 利用继承二次包装标准类 利用授权二次包装标准类 动态模块导入 反射 python提供自省的四个方法: hasattr(object,name) 判断object中有没有有个name字符串 ...
- shell 生成任意大小文件
$ dd if=/dev/zero of=junk.data bs=1M count=1 参数: if (input file) of (output file) bs(block size) co ...
- linxu下redis安装实战
redis官网地址:http://www.redis.io/ 最新版本:2.8.3 在Linux下安装Redis非常简单,具体步骤如下(官网有说明): 1.下载源码,解压缩后编译源码. $ wget ...
- python之map,filter
map和filter是python里面比较重要的BIF,map的主要作用就是对集合里面的每一个元素进行处理,filter的作用就是过滤集合,具体功能如下 t =lambda x:x%2 list(fi ...