题目

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

输入格式

第一行 两个整数 n, k

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

输出格式

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

输入样例

4 3

0 1 1

1 2 2

1 3 4

输出样例

2

提示

2018.1.3新加数据一组,未重测

题解

比较常规的点分治,然而我还是因为不熟练写漏一个判定T得停不下来QAQ

每次找重心,遍历子树维护H数组H[i]表示离根i距离经过的最少边,每次遍历完一个子树,先查询一遍H数组更新答案,再更新H数组,保证不会出现在同一个子树中的情况

遍历完之后,再遍历一遍,把H数组还原【别memset,会T,因为每一层的节点数是不同的,才使得复杂度降低为O(nlogn),而使用memset使得每一层操作都达到n】

之后往下找重心递归

搞完啦~~

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
using namespace std;
const int maxn = 200005,maxm = 1000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
int N,K,h[maxn],ne = 2;
struct EDGE{int to,nxt,w;}ed[2 * maxn];
inline void build(int u,int v,int w){
ed[ne] = (EDGE){v,h[u],w}; h[u] = ne++;
ed[ne] = (EDGE){u,h[v],w}; h[v] = ne++;
}
int F[maxn],rt,Siz[maxn],vis[maxn],sum;
void getRT(int u,int fa){
Siz[u] = 1; F[u] = 0;
Redge(u) if (!vis[to = ed[k].to] && to != fa){
getRT(to,u);
Siz[u] += Siz[to];
F[u] = max(F[u],Siz[to]);
}
F[u] = max(F[u],sum - Siz[u]);
if (F[u] < F[rt]) rt = u;
}
int Dis[maxn],Len[maxn],di = 0,Hd[maxm],dis[maxn],dep[maxn],ansL = INF;
void cal(int u,int fa){
if (dis[u] > K) return;
Dis[++di] = dis[u]; Len[di] = dep[u];
Redge(u) if (!vis[to = ed[k].to] && to != fa){
dis[to] = dis[u] + ed[k].w;
dep[to] = dep[u] + 1;
cal(to,u);
}
}
void solve(int u){
vis[u] = true; Hd[0] = 0;
Redge(u) if (!vis[to = ed[k].to]){
di = 0; dis[to] = ed[k].w; dep[to] = 1;
cal(to,u);
REP(i,di) if (Hd[K - Dis[i]] + Len[i] < ansL)
ansL = Hd[K - Dis[i]] + Len[i];
REP(i,di) if (Hd[Dis[i]] > Len[i])
Hd[Dis[i]] = Len[i];
}
Redge(u) if (!vis[to = ed[k].to]){
di = 0; dis[to] = ed[k].w; dep[to] = 1;
cal(to,u);
REP(i,di) Hd[Dis[i]] = INF;
}
Hd[0] = INF;
Redge(u) if (!vis[to = ed[k].to]){
sum = Siz[to]; F[rt = 0] = INF;
getRT(to,u);
solve(rt);
}
}
int main(){
//freopen("in.txt","r",stdin);
//freopen("out1.txt","w",stdout);
N = read(); K = read(); int u,v,w;
for (int i = 0; i < maxm; i++) Hd[i] = INF;
REP(i,N - 1) u = read() + 1,v = read() + 1,w = read(),build(u,v,w);
F[rt = 0] = INF; sum = N;
getRT(1,0);
solve(rt);
if (ansL == INF) printf("-1\n");
else printf("%d\n",ansL);
return 0;
}

BZOJ2599 [IOI2011]Race 【点分治】的更多相关文章

  1. [bzoj2599][IOI2011]Race——点分治

    Brief Description 给定一棵带权树,你需要找到一个点对,他们之间的距离为k,且路径中间的边的个数最少. Algorithm Analyse 我们考虑点分治. 对于子树,我们递归处理,所 ...

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

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

  3. 【BZOJ-2599】Race 点分治

    2599: [IOI2011]Race Time Limit: 70 Sec  Memory Limit: 128 MBSubmit: 2590  Solved: 769[Submit][Status ...

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

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

  5. [IOI2011]Race 点分治

    [IOI2011]Race LG传送门 点分治板子题. 直接点分治统计,统计的时候开个桶维护下就好了. 注(tiao)意(le)细(hen)节(jiu). #include<cstdio> ...

  6. bzoj2599: [IOI2011]Race(点分治)

    写了四五道点分治的题目了,算是比较理解点分治是什么东西了吧= = 点分治主要用来解决点对之间的问题的,比如距离为不大于K的点有多少对. 这道题要求距离等于K的点对中连接两点的最小边数. 那么其实道理是 ...

  7. [luogu4149][bzoj2599][IOI2011]Race【点分治】

    题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 K,且边的数量最小. 题解 比较明显需要用到点分治,我们定义\(d\)数组表示当前节点到根节点\(rt\)之间有多少个节点,也可以表示有多少 ...

  8. bzoj2599/luogu4149 [IOI2011]Race (点分治)

    点分治.WA了一万年. 重点就是统计答案的方法 做法一(洛谷AC bzojWA 自测WA): 做点x时记到x距离为k的边数最小值为dis[k],然后对每一对有值的dis[i]和dis[K-i],给an ...

  9. 2019.01.09 bzoj2599: [IOI2011]Race(点分治)

    传送门 题意:给一棵树,每条边有权.求一条路径,权值和等于K,且边的数量最小. 思路: 考虑点分治如何合并. 我们利用树形dpdpdp求树的直径的方法,边dfsdfsdfs子树边统计答案即可. 代码: ...

随机推荐

  1. 【MYSQL笔记1】mysql的基础知识

    首先进去mysql.打开电脑命令提示符(cmd):输入mysql -uroot -p   代表的意思是使用ruser使用者root的方式,打开mysql,-p代表password,如果有的话,回车之后 ...

  2. sqlite的sql常用语句(笔记)

    1.复制一张表并重命名 比如已经创建好一个表 表名为"28165" 复制这个表. CREATE TABLE [33150] AS SELECT * FROM [28165] 2.根 ...

  3. JQuery制作网页—— 第三章 JavaScript操作DOM对象

    1. DOM:Document Object Model(文档对象模型):          DOM操作:                   ●DOM是Document Object Model的缩 ...

  4. webmin纯web界面管理linux系统

    关键字: 摘要:从Windows环境的管理转到Linux环境的管理时所面临的挑战之一是,您需要去学习利用新的工具.作为一个管理员,您希望理解操作系统的细节以发挥它的最大功效.但是,当您还处在学习阶段时 ...

  5. 解答室内定位技术新方向:蓝牙AoA定位,值得了解 ——概念了解

    转载搜狐 室内定位一直被炒的非常火的黑科技,也是近年资本追逐的热点,市场上一直有众多宣称可以做到厘米级,米级精度定位的公司,但问题很多,无法大规模商用.近些年有很多人尝试使用蓝牙beacon方式做定位 ...

  6. 笔记-python-多线程-深入-1

    笔记-python-多线程-深入-1 1.      线程池 1.1.    线程池:控制同时存在的线程数量 threading没有线程池,只能自己控制线程数量. 基本有两种方式: 每间隔一段时间创建 ...

  7. JS中调用android和ios系统手机打开相机并可选择相册功能

    编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/57626154 实现android手机打开相机选择相册 ...

  8. kafka生产者与消费者的生产消息与消费消息所遇到的问题

    当我们用API写kafka的时候 生产者生产消息,但是消费者接收不到消息?集群上启动消费者显示生产的消息.我们需要修改一下配置 (1)我们打开在虚拟机中修改kafka集群的配置文件 [root@spa ...

  9. python datetime offset-aware与offset-navie相互转换

    python datetime offset-aware与offset-navie相互转换 2016年11月13日 16:20:43 阅读数:2393 有时,我们使用python 的datetime模 ...

  10. 用swoole实现nginx日志解析

    1.原技术路线解析 在nging配置中将日志信息交给syslog处理,rsyslog配置中将数据传递给了514端口解析,然后将解析好的数据传入elasticsearch中. nginx配置 serve ...