2599: [IOI2011]Race

Time Limit: 70 Sec  Memory Limit: 128 MB
Submit: 3642  Solved: 1081
[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
 
/*
开一个100W的数组t,t[i]表示权值为i的路径最少边数
找到重心分成若干子树后, 得出一棵子树的所有点到根的权值和x,到根a条边,用t[k-x]+a更新答案,全部查询完后
然后再用所有a更新t[x]
这样可以保证不出现点分治中的不合法情况
把一棵树的所有子树搞完后再遍历所有子树恢复T数组,如果用memset应该会比较慢
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> #define inf 1000000000
#define maxn 1000005
#define maxx 200005 using namespace std; int n,K,cnt,sum,root,ans,x,y,z;
int tot[maxn],head[maxx],son[maxx],f[maxx],dis[maxx],d[maxx];
bool vis[maxx];
struct edge
{
int to,next,w;
}e[maxx<<]; inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} void add(int u,int v,int w)
{
e[++cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;
} void get_root(int now,int fa)
{
son[now]=;f[now]=;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa&&!vis[v])
{
get_root(v,now);
son[now]+=son[v];f[now]=max(f[now],son[v]);
}
}
f[now]=max(f[now],sum-son[now]);
if(f[now]<f[root]) root=now;
} void cal(int now,int fa)
{
if(dis[now]<=K) ans=min(ans,d[now]+tot[K-dis[now]]);
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v]&&v!=fa)
{
d[v]=d[now]+;
dis[v]=dis[now]+e[i].w;
cal(v,now);
}
}
} void updata(int now,int fa,int flag)
{
if(dis[now]<=K)
{
if(flag) tot[dis[now]]=min(tot[dis[now]],d[now]);
else tot[dis[now]]=inf;
}
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v]&&v!=fa)
updata(v,now,flag);
}
} void work(int now)
{
vis[now]=;tot[]=;
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
{
d[v]=;dis[v]=e[i].w;
cal(v,);updata(v,,);
}
}
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
updata(v,,);//去掉重心之后要重新统计
}
for(int i=head[now];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
{
root=;sum=son[v];
get_root(v,);
work(root);
}
}
} int main()
{
n=read();K=read();
for(int i=;i<=K;i++)tot[i]=n;
for(int i=;i<n;i++)
{
x=read();y=read();z=read();
x++;y++;
add(x,y,z);add(y,x,z);
}
ans=sum=f[]=n;get_root(,);
work(root);
if(ans!=n)printf("%d\n",ans);
else puts("-1");
return ;
}

bzoj 2599(点分治)的更多相关文章

  1. bzoj 2599 数分治 点剖分

    具体可以见漆子超的论文 /**************************************************************     Problem:     User: B ...

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

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

  3. 【BZOJ 2599】【IOI 2011】Race 点分治

    裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...

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

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

  5. BZOJ 2599 Race(树分治)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 题意:每次 ...

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

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

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

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

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

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

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

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

随机推荐

  1. c#中通过事件实现按下回车跳转控件

    //接受用户输入参数后回车事件 private void tb_KeyPress(object sender, KeyPressEventArgs e) { ) { SendKeys.Send(&qu ...

  2. js的加法操作表

    Number + Number -> 加法 Boolean + Number -> 加法 Boolean + Boolean -> 加法 Number + String -> ...

  3. Java字符字符串类

    Java字符字符串类 Character 类 Character 类用于对单个字符进行操作.Character 类在对象中包装一个基本类型 char 的值在实际开发过程中,我们经常会遇到需要使用对象, ...

  4. selenium之浏览器驱动

    selenium需要配合浏览器的驱动使用,几个主要的浏览器驱动如下 浏览器 链接 Chrome https://sites.google.com/a/chromium.org/chromedriver ...

  5. Centos 7中,防火墙配置端口规则

    注意:firewalld服务有两份规则策略配置记录,配置永久生效的策略记录时,需要执行"reload"参数后才能立即生效: Permanent:永久生效的 RunTime:现在正在 ...

  6. UTL

    在PL/SQL中,UTL_FILE包提供文本文件输入和输出功能. 可以访问的目录通过初始化参数UTL_FILE_DIR设置. 注意:UTL_FILE只能读取服务器端文本文件,不能读取二进制文件.这时候 ...

  7. 2019-02-13 Python爬虫问题 NotImplementedError: Only the following pseudo-classes are implemented: nth-of-type.

    soup=BeautifulSoup(html.text,'lxml') #data=soup.select('body > div.main > div.ctr > div > ...

  8. 【Codeforces 1106D】Lunar New Year and a Wander

    [链接] 我是链接,点我呀:) [题意] 让你遍历n个节点,访问过的节点不操作. 如果是没有访问过的点,那就把它加到序列的末尾. 问你形成的最小字典序的序列是多少. [题解] 显然每次找最小的标号 用 ...

  9. broker监控dataguard配置

    使用broker查看dataguard信息时有告警 DGMGRL> show configuration; Configuration - DRTEST Protection Mode: Max ...

  10. 浅析gcc、arm-linux-gcc和arm-elf-gcc关系

    浅析gcc.arm-linux-gcc和arm-elf-gcc关系 一.GCC简介 The GNU Compiler Collection,通常简称 GCC,是一套由 GNU 开发的编译器集,为什么是 ...