题目

给一棵树,每条边有权.求一条简单路径,权值和等于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. hdu_3501_Calculation 2

    Given a positive integer N, your task is to calculate the sum of the positive integers less than N w ...

  2. springMVC-数据绑定

    定义: 将http请求中参数绑定到Handler业务方法 常用数据绑定类型 1.  基本数据类型 不能为其它类型和null值 2.  包装类 可以为其它对象,全部转成null值 3.  数组 多个对象 ...

  3. 统计重复IP并排序

    #降序排列 sort ip20180623.log | uniq -c | sort -rn | more #可以输出到文件哦 sort ip20180623.log | uniq -c | sort ...

  4. yarn 无法下载node-sass

    指定node-sass的下载源 yarn config set sass-binary-site http://npm.taobao.org/mirrors/node-sass

  5. Oracle 11g R2在 win7 64位的安装流程图解【含常见问题解决方案】

    ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一.Oracle 11 ...

  6. 微信小程序真机定位问题技巧

    小程序导航 https://wq.xmaht.top 开发者在开发小程序的时候可能会碰到一些这样的问题: 问题1  开发者工具上看效果没问题,但是在真机上测试不行? 问题2  有用户遇到小程序功能无法 ...

  7. 浅谈UWB(超宽带)室内定位技术(转载)

    技术背景 随着无线通信技术的发展和数据处理能力的提高,基于位置的服务成为最有前途的互联网业务之一.无论移动在室内还是室外环境下,快速准确地获得移动终端的位置信息和提供位置服务的需求变得日益迫切.通信和 ...

  8. 裸机——LCD

    1.先了解显示器们 CRT显示器 原理,使用电子轰击荧光粉实现显示. 特点,主动发光,颜色绚丽,但是大. 等离子显示器(PDP) 原理,在显示屏上排列上千个密封的小低压气体室,通过电流激发使其发出肉眼 ...

  9. SpringMVC---web.xml配置详解

    web.xml中需要配置的内容 1.配置监听器<listener> 它有两个监听器: 1). <!--配置文件加载监听器--> <listener> <lis ...

  10. __bridge 使用注意

    前奏 在平常开发中,我们可能遇到 CoreFoundation(CF) 框架的对象和 OC 对象之间的类型转换,这时候我们需要 __bridge 来帮忙 注意 : 如果是使用 CF __bridge ...