2599: [IOI2011]Race

Time Limit: 70 Sec  Memory Limit: 128 MB
Submit:
2590  Solved: 769
[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

$N<=200000,K<=1000000$

Source

Solution

树的点分治裸题,但是做法有点有趣

开始考虑的是:

正常的点分,然后每次用当前根开始BFS子树,以获得子树中每个节点到根的边权和和路径长度,并利用之前的结果和当前结果更新答案

不过貌似写挂了50s左右炸掉- -

发现其实不需要,只需要开一个100W的数组来记录 当前到根的距离为$i$的路径长度最短值

这样就可以不断对子树进行更新和对答案进行更新了

时间复杂度依旧是$O(nlogn)$

Code

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
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;
}
#define maxn 200010
#define maxk 1000010
#define inf 0x3f3f3f3f
int n,K;
struct EdgeNode{int next,to,val;}edge[maxn<<];
int head[maxn],cnt=;
void add(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].val=w;}
void insert(int u,int v,int w) {add(u,v,w); add(v,u,w);}
int size[maxn],maxx[maxn],num[maxk],siz,root,ans;
bool visit[maxn];
void Getroot(int now,int last)
{
size[now]=; maxx[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last && !visit[edge[i].to])
{
Getroot(edge[i].to,now);
size[now]+=size[edge[i].to];
maxx[now]=max(maxx[now],size[edge[i].to]);
}
maxx[now]=max(maxx[now],siz-size[now]);
if (maxx[now]<maxx[root]) root=now;
}
struct Node{int d,t;}st[maxn];
int s,top;
void DFS(int now,int dis,int tt,int last)
{
if (dis>K) return;
ans=min(ans,tt+num[K-dis]);
st[top++]=Node{dis,tt};
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last && !visit[edge[i].to])
DFS(edge[i].to,dis+edge[i].val,tt+,now);
}
void Solve(int now)
{
root=; Getroot(now,); now=root;
s=,top=;
for (int i=head[now]; i; i=edge[i].next)
if (!visit[edge[i].to])
{
DFS(edge[i].to,edge[i].val,,now);
for (int j=s; j<=top-; j++)
num[st[j].d]=min(num[st[j].d],st[j].t);
s=top;
}
for (int i=; i<=top-; i++) num[st[i].d]=inf; num[]=;
visit[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (!visit[edge[i].to])
siz=size[edge[i].to],Solve(edge[i].to);
}
int main()
{
n=read(); K=read();
for (int u,v,w,i=; i<=n-; i++) u=read()+,v=read()+,w=read(),insert(u,v,w);
memset(num,inf,sizeof(num)); num[]=;
ans=inf;
siz=maxx[]=n; Solve();
if (ans!=inf) {printf("%d\n",ans); return ;}
puts("-1");
return ;
}

AC第一道IOI   ovo!

【BZOJ-2599】Race 点分治的更多相关文章

  1. BZOJ 2599 Race(树分治)

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

  2. [BZOJ 3456]城市规划(cdq分治+FFT)

    [BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...

  3. [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)

    [BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. js继承《转》

    http://www.jb51.net/article/55540.htm http://www.cnblogs.com/OceanHeaven/p/4965947.html http://www.j ...

  2. mac系统使用内置的 PHP

    从 OS X 10.0.0 版本开始,PHP 作为 Mac 机的标准配置被提供.在默认的 web 服务器中启用 PHP,只需将 Apache 配置文件 httpd.conf 中的几行配置指令最前面的注 ...

  3. iOS多线程杂论

    iOS多线程的分布 (1) NSThread (2) NSOperation (3) GCD 现在对下面三个进行一个个的分析,希望那里说得不对的地方希望简友们帮我指点一二. 1,NSThread 优点 ...

  4. spring:如何用代码动态向容器中添加或移除Bean ?

    先来看一张类图: 有一个业务接口IFoo,提供了二个实现类:FooA及FooB,默认情况下,FooA使用@Component由Spring自动装配,如果出于某种原因,在运行时需要将IFoo的实现,则F ...

  5. 模拟MVC-WebForm实现ModelBinding

    (一) 前言                                                                           用ASP.NET MVC的时候,我们都 ...

  6. C/C++实践笔记_001Helloworld

    1.void返回值为空,int返回值Linux c,c++中,Main函数可以返回也可以不返回,普通函数必须返回.C编译松散,很容易结果出错,C++编译严格一些,结果一般会正确C语言不返回不会报错,但 ...

  7. Quartz.NET 入门

    概述 Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了 ...

  8. javascript 连等赋值问题(这是从SegmentFault转过来的一个问题)

    var a = {n:1}; var b = a; // 持有a,以回查 a.x = a = {n:2}; alert(a.x);// --> undefined alert(b.x);// - ...

  9. Win7宽带一键创建

    简化创建宽带连接步骤,为简便而生. 不断分享,不断进步. 免费下载:                  http://yunpan.cn/cmZesi2jpJk9E  访问密码 9444

  10. 【Alpha版本】冲刺阶段——Day 3

    我说的都队 031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬 ...