【BZOJ-2599】Race 点分治
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
0 1 1
1 2 2
1 3
4
Sample Output
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 点分治的更多相关文章
- BZOJ 2599 Race(树分治)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2599 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 题意:每次 ...
- [BZOJ 3456]城市规划(cdq分治+FFT)
[BZOJ 3456]城市规划(cdq分治+FFT) 题面 求有标号n个点无向连通图数目. 分析 设\(f(i)\)表示\(i\)个点组成的无向连通图数量,\(g(i)\)表示\(i\)个点的图的数量 ...
- [BZOJ 2989]数列(CDQ 分治+曼哈顿距离与切比雪夫距离的转化)
[BZOJ 2989]数列(CDQ 分治) 题面 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]| ...
- BZOJ 2599: [IOI2011]Race( 点分治 )
数据范围是N:20w, K100w. 点分治, 我们只需考虑经过当前树根的方案. K最大只有100w, 直接开个数组CNT[x]表示与当前树根距离为x的最少边数, 然后就可以对根的子树依次dfs并更新 ...
- 【BZOJ 2599】【IOI 2011】Race 点分治
裸的点分治,然而我因为循环赋值$s$时把$i <= k$写成$i <= n$了,WA了好长时间 #include<cstdio> #include<cstring> ...
- bzoj 2599 [IOI2011]Race (点分治)
[题意] 问树中长为k的路径中包含边数最少的路径所包含的边数. [思路] 统计经过根的路径.假设当前枚举到根的第S个子树,若x属于S子树,则有: ans<-dep[x]+min{ dep[y] ...
- BZOJ 2599 [IOI2011]Race【Tree,点分治】
给出N(1 <= N <= 200000)个结点的树,求长度等于K(1 <= K <= 1000000)的路径的最小边数. 点分治,这道题目和POJ 2114很接近,2114是 ...
- bzoj 2599: [IOI2011]Race (点分治 本地过了就是过了.jpg)
题面:(复制别人的...) Description 给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. Input 第一行 两个整数 n, k第二..n行 每行三个整数 表示一条无向边的 ...
- 【BZOJ】2599: [IOI2011]Race 点分治
[题意]给一棵树,每条边有权.求一条简单路径,权值和等于K,且边的数量最小.N <= 200000, K <= 1000000.注意点从0开始编号,无解输出-1. [算法]点分治 [题解] ...
- bzoj 2599: [IOI2011]Race【点分治】
点分治,用一个mn[v]数组记录当前root下长为v的链的最小深度,每次新加一个儿子的时候都在原来儿子更新过的mn数组里更新ans(也就是查一下mn[m-dis[p]]+de[p]) 这里注意更新和初 ...
随机推荐
- eclipse服务器add and remove 工程时出现there are no resources that can be added or removed from the server
网上的解决方法: 解决方法: 第1步.新建一个“Dynamic Web Project” 第2步.把新建项目里面的.project文件和.settings文件夹复制到导入的那个项目里面. 可是我发现: ...
- Eclipse中启用Oracle jdbc logging
根据自己用的JRE版本, jre1.5选择ojdbc5_g.jar, jre6选择ojdbc6_g.jar, 只有带_g的dirver才输出debug信息. maven 的配置信息: <depe ...
- Broadmann area (wiki)
Source: https://en.wikipedia.org/wiki/Brodmann_area Lateral surface Medial serface Areas 3, 1 & ...
- NOI2018准备 Day9
tjvj清北入学测试又打了一上午,暴力搜索得了部分分,dp全崩了,8道题凑了500分. 下午打了个速度赛,成绩未知,另外又做了1道题,这效率low到爆!!!
- Effective java 第2版 - 笔记(01) 单例(Singleton)的枚举(enum)实现
直接上代码: public enum Boss { INSTANCE; private String name; public void doSomeThing() { System.out.prin ...
- 产品列表页分类筛选、排序的算法实现(PHP)
一.简单的单条件查询 工作都是从简单的开始,先从最简单的单表查询开始,这个一般用在首页以及一些比较独立的页面,只需要查找几个符合条件的产品展示出来即可,可以使用分页或者不使用分页.下面这个是产品控制器 ...
- ASP.NET + SqlSever 大数据解决方案 PK HADOOP
半个月前看到博客园有人说.NET不行那篇文章,我只想说你们有时间去抱怨不如多写些实在的东西. 1.SQLSERVER优点和缺点? 优点:支持索引.事务.安全性以及容错性高 缺点:数据量达到100万以 ...
- C# WinForm应用程序降低系统内存占用方法
这里整理了一些网上关于Winform如何降低系统内存占用的资料,供参考: 1.使用性能测试工具dotTrace 3.0,它能够计算出你程序中那些代码占用内存较多2.强制垃圾回收3.创建完对象实例后,记 ...
- 用SpringMvc实现Excel导出功能
以前只知道用poi导出Excel,最近用了SpringMvc的Excel导出功能,结合jxl和poi实现,的确比只用Poi好,两种实现方式如下: 一.结合jxl实现: 1.引入jxl的所需jar包: ...
- 《Android性能优化》学习笔记链接<转载>
今天找到一博文汇总了 Android性能优化 比较好的文章 ,本计划全看完,自己再精简下,因篇幅太长,先收藏了,等有时间 再仔细拜读,总结自己的看法: 第一季: http://www.csdn.ne ...