【题意】

问树中长为k的路径中包含边数最少的路径所包含的边数。

【思路】

统计经过根的路径。假设当前枚举到根的第S个子树,若x属于S子树,则有:

ans<-dep[x]+min{ dep[y] },y属于前S-1个子树,dis[x]<=K

所以只需要用一个数组t[len]记录前S-1棵子树中长度为len的最少边数即可。t只用开到K的最大值。

然后分治处理子树。

【代码】

 #include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 1e6+;
const int inf = 1e9; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge {
int v,w,nxt;
}e[N<<];
int en=,front[N];
void adde(int u,int v,int w)
{
e[++en]=(Edge){v,w,front[u]}; front[u]=en;
} int l1,l2;
int t[N],dep[N],dis[N],ans=inf,list[N];
int vis[N],siz[N],rt,f[N],size,n,K; void getroot(int u,int fa)
{
siz[u]=; f[u]=;
trav(u,i) if(e[i].v!=fa&&!vis[e[i].v]){
int v=e[i].v;
getroot(v,u);
siz[u]+=siz[v];
f[u]=max(f[u],siz[v]);
}
f[u]=max(f[u],size-siz[u]);
if(f[u]<f[rt]) rt=u;
}
void dfs(int u,int fa)
{
list[++l1]=u;
trav(u,i) if(e[i].v!=fa&&!vis[e[i].v]) {
int v=e[i].v;
dis[v]=dis[u]+e[i].w;
dep[v]=dep[u]+;
dfs(v,u);
}
}
void solve(int u)
{
vis[u]=; t[]=;
l1=l2=;
trav(u,i) if(!vis[e[i].v]) {
int v=e[i].v;
dep[v]=; dis[v]=e[i].w;
dfs(v,-);
FOR(j,l2+,l1) {
if(dis[list[j]]<=K)
ans=min(ans,dep[list[j]]+t[K-dis[list[j]]]);
}
FOR(j,l2+,l1)
if(dis[list[j]]<=K) t[dis[list[j]]]=min(t[dis[list[j]]],dep[list[j]]);
l2=l1;
}
FOR(i,,l1) t[dis[list[i]]]=inf;
trav(u,i) if(!vis[e[i].v]) {
int v=e[i].v; rt=;
getroot(v,-); size=siz[v];
solve(rt);
}
} int main()
{
freopen("in.in","r",stdin);
freopen("out.out","w",stdout);
n=read(),K=read();
int u,v,w;
FOR(i,,n-) {
u=read()+,v=read()+,w=read();
adde(u,v,w),adde(v,u,w);
}
FOR(i,,K) t[i]=n;
size=f[]=ans=n;
getroot(,-);
solve(rt);
if(ans==n) puts("-1");
else printf("%d\n",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【Tree,点分治】

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

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

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

  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. 漫谈C语言及如何学习C语言

    抄自:http://my.oschina.net/apeng/blog/137911 目录:[ - ] 为什么要学习C语言? C语言学习方法 1,参考书籍 2,动手实验环境搭建 3,网络资源 附录 一 ...

  2. KDE/QT与GNOME/GTK比较

    转自:http://linux.chinaunix.net/bbs/thread-1125240-1-1.html 虽然在商业方面存在竞争,GNOME与KDE两大阵营的开发者关系并没有变得更糟,相反他 ...

  3. Failed to execute goal.....webxml attribute is required...

    maven在打包项目的时候报错 Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-wa ...

  4. 246. Strobogrammatic Number

    题目: A strobogrammatic number is a number that looks the same when rotated 180 degrees (looked at ups ...

  5. shell脚本 -d 是目录文件,那么-e,-f等说明

    -e filename 如果 filename存在,则为真 -d filename 如果 filename为目录,则为真 -f filename 如果 filename为常规文件,则为真 -L fil ...

  6. shell 数学计算

    每次都找不到一个好的方法来执行shell中的变量计算. 前段时间忘了在哪发现一个好的方法.在此记录下来. 申请变量: value=0; 变量加减: value=$[$value+1] 变量乘除: va ...

  7. HTML CSS3 手风琴菜单

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel= ...

  8. linux中proc文件系统 -- ldd3读书笔记

    1./proc 文件系统概述 /proc 文件系统是由软件创建,被内核用来向外界报告信息的一个文件系统./proc 下面的每一个文件都和一个内核函数相关联,当文件的被读取时,与之对应的内核函数用于产生 ...

  9. SharePoint2010安装文档

    最低配置要求 操作系统 X64 Window Server 2008 R2 Standard 数据库 X64 SQL Server 2008 R2 CPU X64,4核 内存 8G 硬盘 100G 安 ...

  10. CXF客户端异常

    基于CXF2.3.0 Caused by: java.lang.InstantiationException: org.apache.cxf.wstx_msv_validation.WoodstoxV ...