bzoj 2599 [IOI2011]Race 点分

时间:2022-12-08 09:34:55

[IOI2011]Race

Time Limit: 70 Sec  Memory Limit: 128 MB
Submit: 4768  Solved: 1393
[Submit][Status][Discuss]

Description

给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000

Input

第一行 两个整数 n, k
第二..n行 每行三个整数 表示一条无向边的两端和权值 (注意点的编号从0开始)

Output

一个整数 表示最小边数量 如果不存在这样的路径 输出-1

Sample Input

4 3
0 1 1
1 2 2
1 3 4

Sample Output

2

HINT

2018.1.3新加数据一组,未重测

点分治模板题

 #include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<map> #define ll long long
#define inf 1000000007
#define N 200007
using namespace std;
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int num=;
int n,k;
int total,id,f[N],siz[N];
ll tot,a[N];
int bs[N];
int ans=inf;
bool vis[N];
int cnt,hed[N],rea[N<<],nxt[N<<],val[N<<];
map<ll,int>p; void add(int u,int v,int z)
{
nxt[++cnt]=hed[u];
hed[u]=cnt;
rea[cnt]=v;
val[cnt]=z;
}
void add_two_way(int x,int y,int z)
{
add(x,y,z);
add(y,x,z);
}
void get_heart(int u,int fa)
{
siz[u]=,f[u]=;
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i];
if (v==fa||vis[v]) continue;
get_heart(v,u);
siz[u]+=siz[v],f[u]=max(f[u],siz[v]);
}
f[u]=max(f[u],total-siz[u]);
if (f[u]<f[id]) id=u;
}
void dfs(int u,int fa)
{
int now=tot;
if (a[tot]==k) ans=min(ans,bs[tot]);
if (p[k-a[tot]]) ans=min(ans,p[k-a[tot]]+bs[tot]);
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i],fee=val[i];
if (fa==v||vis[v]) continue;
bs[++tot]=bs[now]+,a[tot]=a[now]+fee;
dfs(v,u);
}
}
void calc(int u)
{
map<ll,int>z;
swap(p,z),bs[u]=;
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i],fee=val[i];
if (vis[v]) continue;
bs[++tot]=,a[tot]=fee;
dfs(v,u);
for (int i=;i<=tot;i++)
if (!p[a[i]]) p[a[i]]=bs[i];
else p[a[i]]=min(p[a[i]],bs[i]);
tot=;
}
}
void solve(int u)
{
vis[u]=true;calc(u);int sum=total;
for (int i=hed[u];i!=-;i=nxt[i])
{
int v=rea[i];
if (vis[v]) continue;
total=(siz[v]>siz[u])?sum-siz[u]:siz[v];
id=,get_heart(v,u);
solve(id);
}
}
int main()
{
freopen("fzy.in","r",stdin);
// freopen("fzy.out","w",stdout); memset(hed,-,sizeof(hed));
n=read(),k=read();
for (int i=;i<n;i++)
{
int x=read(),y=read(),z=read();x++,y++;
add_two_way(x,y,z);
}
total=f[]=n;
get_heart(,);
solve(id);
if (ans==inf) puts("-1");
else printf("%d\n",ans);
}

bzoj 2599 [IOI2011]Race 点分的更多相关文章

  1. BZOJ 2599&colon; &lbrack;IOI2011&rsqb;Race&lpar; 点分治 &rpar;

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

  2. 【刷题】BZOJ 2599 &lbrack;IOI2011&rsqb;Race

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

  3. bzoj 2599&colon; &lbrack;IOI2011&rsqb;Race &lpar;点分治 本地过了就是过了&period;jpg&rpar;

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

  4. bzoj 2599 &lbrack;IOI2011&rsqb;Race (点分治)

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

  5. BZOJ 2599 &lbrack;IOI2011&rsqb;Race【Tree,点分治】

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

  6. BZOJ 2599&colon; &lbrack;IOI2011&rsqb;Race

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

  7. bzoj 2599&colon; &lbrack;IOI2011&rsqb;Race【点分治】

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

  8. 2599&colon; &lbrack;IOI2011&rsqb;Race

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

  9. 【BZOJ】2599&colon; &lbrack;IOI2011&rsqb;Race 点分治

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

随机推荐

  1. html meta标签使用总结

    meta标签作用 META标签是HTML标记HEAD区的一个关键标签,提供文档字符集.使用语言.作者等基本信息,以及对关键词和网页等级的设定等,最大的作用是能够做搜索引擎优化(SEO). PS:便于搜 ...

  2. 【ubuntu java】java&colon; error while loading shared libraries&colon; libjli&period;so&colon; cannot open shared object file&colon; No such file or directory

    先检查了环境变量PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/loca ...

  3. sql语句聚合等疑难问题收集

    ------------------------------------------------------------------------------------ 除法运算 select 500 ...

  4. Git(一)环境搭建 &plus; 常用命令

    上周研究了一下 Git,简单的使用了一下,个人感觉相对 SVN 来说还是有一定学习成本的,这次记录一些自己的学习过程以及常用的命令. 在学习的过程中,同事推荐了一个前辈写的教程([传送门]:Git教程 ...

  5. bzoj1965 &lbrack;Ahoi2005&rsqb;SHUFFLE 洗牌

    Description 为了表彰小联为Samuel星球的探险所做出的贡献,小联被邀请参加Samuel星球近距离载人探险活动. 由于Samuel星球相当遥远,科学家们要在飞船中度过相当长的一段时间,小联 ...

  6. MATLAB &&num;39&semi; &colon; &&num;39&semi; 官方解释

    1.冒号的作用 产生矢量,阵列标注以及for-loop迭代子 2.描述 冒号是MATLAB中最有用的操作符之一.它使用下述规则来创建有规则的空间矢量: j:k is the same as [j,j+ ...

  7. ContextLoaderListener加载过程

    在web.xml中,配置ContextLoaderListener <!-- 配置Listener,用来创建Spring容器 --> <listener> <listen ...

  8. Python中的7种可调用对象

    Python中有七种可调用对象,可调用对象可使用内置函数callable来检测 一.用户自定义的函数: 使用def语句或者lambda表达式创建的函数. 二.内置函数: 使用C语言实现的函数,如len ...

  9. UDP网络通信

    网络概念 一.目的 二.IP地址 三.端口 一.目的 目的 : 主要用于让两个用户端的服务器或者客户端,可以实现资源共享和信息传递 二.IP地址 1.作用 : 计算机网络中一台计算机的标识 2.种类 ...

  10. poj 3630 Phone List 贪心

    Phone List Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23722   Accepted: 7289 Descr ...