模板—点分治B(合并子树)(洛谷P4149 [IOI2011]Race)
点分治作用(目前只知道这个):
求一棵树上满足条件的节点二元组(u,v)个数,比较典型的是求dis(u,v)(dis表示距离)满足条件的(u,v)个数。
算了自己懒得写了,安利几个blog吧:
https://www.cnblogs.com/LadyLex/p/8006488.html
https://blog.csdn.net/qq_39553725/article/details/77542223
https://blog.csdn.net/zzkksunboy/article/details/70244945
#include<iostream>
#include<cstring>
#include<cstdio>
#define int long long
#define MAXN 200010
#define INF 100000000
using namespace std;
struct edge
{
int u,v,w,nxt;
#define u(x) ed[x].u
#define v(x) ed[x].v
#define w(x) ed[x].w
#define n(x) ed[x].nxt
}ed[MAXN*2];
int first[MAXN],num_e;
#define f(x) first[x]
int sum,mn,root;
int siz[MAXN],mxsiz[MAXN];
bool v[MAXN];
int n,k;
int ans=INF,t[1000010];
int dis[MAXN],dep[MAXN];
void getroot(int x,int fa)//查找根节点,没什么可说的。
{
siz[x]=1,mxsiz[x]=0;
for(int i=f(x);i;i=n(i))
if(!v[v(i)]&&v(i)!=fa)
{
getroot(v(i),x);
siz[x]+=siz[v(i)];
mxsiz[x]=max(siz[v(i)],mxsiz[x]);
}
mxsiz[x]=max(mxsiz[x],sum-siz[x]);
if(mxsiz[x]<mn)mn=mxsiz[x],root=x;
}
void cal(int x,int fa)//更新答案
{
if(dis[x]<=k)ans=min(ans,dep[x]+t[k-dis[x]]);
for(int i=f(x);i;i=n(i))
if(!v[v(i)]&&v(i)!=fa)
{
dep[v(i)]=dep[x]+1;
dis[v(i)]=dis[x]+w(i);
cal(v(i),x);
}
}
int add(int x,int fa,int flag)//更新桶
{
if(dis[x]<=k)
{
if(flag)t[dis[x]]=min(t[dis[x]],dep[x]);
else t[dis[x]]=INF;
}
for(int i=f(x);i;i=n(i))
if(v(i)!=fa&&!v[v(i)])
add(v(i),x,flag);
}
void divide(int x)
{
v[x]=1;t[0]=0;
for(int i=f(x);i;i=n(i))
if(!v[v(i)])
{
dep[v(i)]=1,dis[v(i)]=w(i);
cal(v(i),0);//先用这个儿子更新答案,因为更新答案时要用到之前的儿子的信息,有点类似树p。
add(v(i),0,1);//先用这个儿子更新答案,再将这个儿子合并,确保不会出错。
}
for(int i=f(x);i;i=n(i))
if(!v[v(i)])
add(v(i),0,0);//清空桶。
for(int i=f(x);i;i=n(i))
if(!v[v(i)])
{
sum=siz[v(i)],mn=INF;
getroot(v(i),0);
divide(root);//分治树递归。
}
}
inline void adde(int u,int v,int w);
signed main()
{
// freopen("in.txt","r",stdin);
// freopen("1.in","r",stdin); scanf("%lld%lld",&n,&k);
int u,v,w;
for(int i=1;i<n;i++)
{
scanf("%lld%lld%lld",&u,&v,&w);
u++,v++;
adde(u,v,w),adde(v,u,w);
}
memset(t,0x7f,sizeof(t));
sum=n,mn=INF;
getroot(1,0);
divide(root);
if(ans==INF)puts("-1");
else printf("%lld\n",ans);
}
inline void adde(int u,int v,int w)
{
++num_e;
u(num_e)=u;
v(num_e)=v;
w(num_e)=w;
n(num_e)=f(u);
f(u)=num_e;
}
模板—点分治B(合并子树)(洛谷P4149 [IOI2011]Race)的更多相关文章
- 洛谷P4149 [IOI2011]Race(点分治)
题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK ,且边的数量最小. 输入输出格式 输入格式: 第一行:两个整数 n,kn,k . 第二至 nn 行:每行三个整数,表示一条无向边的 ...
- 洛谷$P4149\ [IOI2011]\ Race$ 点分治
正解:点分治 解题报告: 传送门$QwQ$ 昂先不考虑关于那个长度的限制考虑怎么做? 就开个桶,记录所有边的取值,每次加入边的时候查下是否可行就成$QwQ$ 然后现在考虑加入这个长度的限制?就考虑把这 ...
- [洛谷P4149][IOI2011]Race
题目大意:给一棵树,每条边有边权.求一条简单路径,权值和等于$K$,且边的数量最小. 题解:点分治,考虑到这是最小值,不满足可减性,于是点分中的更新答案的地方计算重复的部分要做更改,就用一个数组记录前 ...
- 洛谷 P4149 [IOI2011]Race-树分治(点分治,不容斥版)+读入挂-树上求一条路径,权值和等于 K,且边的数量最小
P4149 [IOI2011]Race 题目描述 给一棵树,每条边有权.求一条简单路径,权值和等于 KK,且边的数量最小. 输入格式 第一行包含两个整数 n, Kn,K. 接下来 n - 1n−1 行 ...
- 洛谷 4149 [IOI2011]Race——点分治
题目:https://www.luogu.org/problemnew/show/P4149 第一道点分治! 点分治大约是每次找重心,以重心为根做一遍树形dp:然后对于该根的每个孩子,递归下去.递归之 ...
- 最短路(模板)【CodeChef CLIQUED,洛谷P3371】
自TG滚粗后咕咕咕了这么久,最近重新开始学OI,也会慢慢开始更博了.... 最短路算法经典的就是SPFA(Bellman-Ford),Dijkstra,Floyd: 本期先讲两个经典的单源最短路算法: ...
- 洛谷 P4149 [ IOI 2011 ] Race —— 点分治
题目:https://www.luogu.org/problemnew/show/P4149 仍然是点分治: 不过因为是取 min ,所以不能用容斥,那么子树之间就必须分开算,记录桶时注意这个: 每次 ...
- LCT模板(学习笔记)(洛谷3690)(加边,删边,修改点权)
最近学习了一波LCT qwq 强势安利Flashhu的博客!!!!! 真的特别详细(可惜我不会弄链接) 如果有想要学习\(LCT\)的同学,可以直接看他的博客 我这里就简单写一点自己的体会啊. \(L ...
- (贪心 优先队列)P1090合并果子 洛谷
题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...
随机推荐
- 直接在安装了redis的Linux机器上操作redis数据存储类型--set类型
一.概述: 在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加.删除或判断某一元素是否存在等操作.需要说明的是,这些操作的时间复 ...
- CSS的color属性并非只能用于文本显示
虽然CSS并不是一种很复杂的技术,但就算你是一个使用CSS多年的高手,仍然会有很多CSS用法/属性/属性值你从来没使用过,甚至从来没听说过. 对于CSS的color属性,相信所有Web开发人员都使用过 ...
- XML解析器之JAXP与DOM4J
XML是一种数据格式,那么需要对XML文件进行操作就需要用到XML解析器---------针对dom方式和sax方式提供了不同的解析技术-----需要不同的XML解析器 dom方式:会把文档中所有元素 ...
- FFT初步代码分析和逼近曲线
FFT:快速傅里叶变换 文章从两个方面来写,一个是FFT的基础知识,也就是将时域信号转换为频域信号,另一个是合成时域信号. 将时域信号转换为频域信号 代码来源于http://bigsec.net/b5 ...
- 快速乘O(1)和O(log)
O(1)快速乘来自骆可强:<论程序底层优化的一些方法与技巧> //O(1)快速乘 inline LL quick_mul(LL x,LL y,LL MOD){ x=x%MOD,y=y%MO ...
- 微信小程序之组件开发中的基础知识
跟着视频开始小程序的项目的开发,视频中这个小程序已经上线了,可以很好的看着小程序的界面进行开发,昨天看了一下具体的需求,觉得真的细节好多啊,而且其中设计的组件的思想也是很好的,能够很好的实现代码的复用 ...
- SVN客户端操作(clean up|commit|update)系统找不到指定的文件
前天电脑中毒,更新SVN的时候,发现以下错误: Can't open file 'XXXXX\.svn\pristine\7a\7ab8cc591cd8b0425a0e6331cc52756d15ba ...
- arcgis图层控制
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- Android——app基础
Android Application基础 系统启动过程 APK文件介绍 APK是Android Package的缩写,即android安装包.APK 文件其实是zip 格式,但后缀名被修改为apk ...
- 全面系统Python3入门+进阶课程
全面系统Python3入门+进阶课程 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的时候 ...