【题意】给一棵树,每条边有权.求一条简单路径,权值和等于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. 将 Spring 和 Hibernate 与 WebSphere Application Server 一起使用

    本文摘要 如果您考虑将 Spring 或 Hibernate 与 IBM® WebSphere® Application Server 一起使用,则本文向您阐述了如何配置这些框架,以适用于 WebSp ...

  2. Objective - C 之延展

    延展:为已有的类新增私有方法,只能在本类中使用 一.创建过程: 二.总结: 1.延展只有.h文件,在其中写新方法的声明,在原本的类(Person)中写方法的实现: 2.上述的方法其实很不安全,因为如果 ...

  3. freemarker中空值 null的处理 ?exists ?if_exists ?default(“”)

    exists:由空值测试运算符的引入,它被废弃了. exp1?exists 和 exp1??是一样的, ( exp1)?exists 和(exp1)??也是一样的. if_exists:由默认值运算符 ...

  4. [ Selenium2 从零开始 by Bruce from http://seleniumcn.cn ] 1-8 视频集锦

    内容转自: http://blog.csdn.net/sxl0727tu/article/details/51887093\ ************************************* ...

  5. linux php 访问sql server设置

    1.安装freeTDS wget ftp://ftp.freetds.org/pub/freetds/stable/freetds-stable.tgz 1.1.进入到你下载的目录然后解压.tar - ...

  6. 第182天:HTML5——地理定位

    HTML5 Geolocation(地理定位) HTML5 Geolocation API 用于获得用户的地理位置. 鉴于该特性可能侵犯用户的隐私,除非用户同意,否则用户位置信息是不可用的. 浏览器支 ...

  7. js null表示没有取到html中的元素 undenfind 表示没有被赋值

    js null表示没有取到html中的元素 undenfind 表示没有被赋值

  8. 【codevs1163】访问艺术馆 树形dp

    题目描述 皮尔是一个出了名的盗画者,他经过数月的精心准备,打算到艺术馆盗画.艺术馆的结构,每条走廊要么分叉为二条走廊,要么通向一个展览室.皮尔知道每个展室里藏画的数量,并且他精确地测量了通过每条走廊的 ...

  9. Java 读取Excel2007 jar包冲突的问题(org.apache.poi.POIXMLException: java.lang.reflect.InvocationTargetException)

    1.jar包冲突报错问题 2.使用的jar包,以及重复jar包 3.删除重复jar包

  10. 二维RMQ模板

    int main(){ ; i <= n; i++) ; j <= m; j++) { scanf("%d", &val[i][j]); dp[i][j][][ ...