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

【算法】点分治

【题解】每个区域按重心x划分子树,一条经过x的路径是从一个子树到另一个子树的(从x出发记为深度0即可),那么就让子树i的路径与子树1~i-1尝试合并,然后并入,这样就可以找到所有路径。

每个区域记录t[i]表示长度为i的路径最小边数,就可以过程中合并时计算答案ans = min{ ans , deep[x]+t[k-dis[x]] } 。

每个区域处理完要把t[]清空,然后再进入各个子区域。清空不能memset(否则复杂度不对),只能清空访问过的点。

复杂度O(n log n)。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=,maxk=;
int first[maxn],tot,sz[maxn],n,root,k,sum,dis[maxn],deep[maxn],ans,t[maxk],c[maxn],L,R;
bool vis[maxn];
struct edge{int v,w,from;}e[maxn*];
void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void getroot(int x,int fa){
sz[x]=;bool ok=;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v]){
getroot(e[i].v,x);
sz[x]+=sz[e[i].v];
if(sz[e[i].v]>sum/)ok=;
}
if(sum-sz[x]<=sum/&&ok)root=x;
}
void dfs(int x,int fa){
if(dis[x]>k)return;
ans=min(ans,deep[x]+t[k-dis[x]]);
c[++R]=x;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa&&!vis[e[i].v]){
dis[e[i].v]=dis[x]+e[i].w;
deep[e[i].v]=deep[x]+;
dfs(e[i].v,x);
}
}
void solve(int x,int s){
vis[x]=;L=;R=;
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
deep[e[i].v]=;dis[e[i].v]=e[i].w;
dfs(e[i].v,x);
for(int j=L+;j<=R;j++)t[dis[c[j]]]=min(t[dis[c[j]]],deep[c[j]]);
L=R;
}
for(int i=;i<=R;i++)t[dis[c[i]]]=n;
for(int i=first[x];i;i=e[i].from)if(!vis[e[i].v]){
if(sz[e[i].v]>sz[x])sum=s-sz[x];else sum=sz[e[i].v];
root=e[i].v;
getroot(e[i].v,x);
solve(root,sum);
}
}
int main(){
scanf("%d%d",&n,&k);
int u,v,w;
for(int i=;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
u++;v++;
insert(u,v,w);insert(v,u,w);
}
root=;sum=n;ans=n;
for(int i=;i<=k;i++)t[i]=n;
getroot(,);
solve(root,n);
if(ans==n)printf("-1");
else printf("%d",ans);
return ;
}

【BZOJ】2599: [IOI2011]Race 点分治的更多相关文章

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

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

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

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

  3. bzoj 2599 [IOI2011]Race 点分

    [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 4768  Solved: 1393[Submit][Status][Dis ...

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

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

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

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

  6. bzoj 2599: [IOI2011]Race【点分治】

    点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...

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

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

  8. BZOJ 2599: [IOI2011]Race

    点分治,定权值,求另一关键字最小 不满足前缀加减性 可以按序遍历,用一数组$t[] 来维护路径为i的最小边数$ 再对于一个直系儿子对应的子树,先算距离求答案再更新$t数组,这样就不会重复$ #incl ...

  9. 2599: [IOI2011]Race

    2599: [IOI2011]Race 链接 分析 被memset卡... 点分治,对于重心,遍历子树,记录一个数组T[i],表示以重心为起点的长度为i的路径中最少的边数是多少.然后先遍历子树,更新答 ...

随机推荐

  1. 求最大子串和以及其中一个子串(java)

    public static void getMaxSum(int[] a){ int max = a[0]; int sum = a[0]; int temp = 0; int start = 0; ...

  2. 201621123037 《Java程序设计》第6周学习总结

    作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多 ...

  3. windows操作系统下载tomcat,并与eclipse进行整合

    进入Tomcat官网之后,在左边我们看到,Tomcat的有6,7,8这三个最流行的版本,我们可以点击进去下载想要的版本. 进入里面之后,可以看见有64位的和32位的,就看自己的电脑是多少位的了,如果电 ...

  4. BPSK相干解调和DBPSK非相干解调误码率仿真

    BPSK相干解调和DBPSK非相干解调误码率仿真 本脚本完成了BPSK和DBPSK两种不同调制方式下的误码率(DBPSK差分相干)仿真, 并和理论曲线进行了对比. 撰写人:*** 最后修改日期:201 ...

  5. MachineLearning ---- lesson 2 Linear Regression with One Variable

    Linear Regression with One Variable model Representation 以上篇博文中的房价预测为例,从图中依次来看,m表示训练集的大小,此处即房价样本数量:x ...

  6. C++解析(16):友元与类中的函数重载

    0.目录 1.友元的尴尬能力 2.类中的函数重载 3.小结 1.友元的尴尬能力 什么是友元? 友元是C++中的一种关系 友元关系发生在函数与类之间或者类与类之间 友元关系是单项的,不能传递 友元的用法 ...

  7. [poi2011]bzoj 2277 —— strongbox·[洛谷3518]

    ·问题描述· 有一个密码箱,0到n-1中的某些数是它的密码.且满足:如果a和b都是它的密码,那么(a+b)%n也是它的密码.某人试了k次密码,前k-1次都失败了,最后一次成功. 问:该密码箱最多有多少 ...

  8. 【UOJ#188】Sanrd(min_25筛)

    [UOJ#188]Sanrd(min_25筛) 题面 UOJ 题解 今天菊开讲的题目.(千古神犇陈菊开,扑通扑通跪下来) 题目要求的就是所有数的次大质因子的和. 这个部分和\(min\_25\)筛中枚 ...

  9. LOJ分块⑨题汇总

    从零开始的分块学习系列(感谢hzwer) 题目顺序是我建议的做题顺序 先说一句:分块的核心思想(其实本身分块就可以说是一种思想)是:均摊(或者说平衡/权衡?)复杂度,同时这种思想本身不只局限于序列分块 ...

  10. 【数学】【CF27E】 Number With The Given Amount Of Divisors

    传送门 Description 给定一个正整数\(n\),输出最小的整数,满足这个整数有n个因子 Input 一行一个整数\(n\) Output 一行一个整数,代表答案. Hint \(1~\leq ...