Codeforces 516D - Drazil and Morning Exercise(树的直径+并查集)
这是一道 jxd 的作业题,感觉难度不是特别大(虽然我并没有自己独立 AC,不过也可能是省选结束了我的脑子也没了罢(((,就随便写写罢
u1s1 这题似乎是 dreamoon 出的呢(
首先我们需求出 \(d_x\) 即 \(\max\limits_{y=1}^n\text{dist}(x,y)\),这个想怎么求怎么求,可以使用换根 \(dp\),也可以用树的直径,复杂度 \(\mathcal O(n)\)
求完之后该怎么做呢?注意到 \(q\) 很小,因此有一个很显然的想法是将所有点按 \(d\) 从小到大排序然后暴力双针+LCT,不过一来我不会 LCT,二来这样询问复杂度会达到 \(n\log n\),虽然应该可以通过,但并不优秀,因此我们暂时不讲这个做法。我们不妨来探究 \(d\) 的性质,记 \(r\) 为使 \(d_u\) 取到最小值的 \(u\),显然 \(u\) 在树的直径上,否则我们可以将其移到直径上并使得 \(d\) 值不会变得更大。
我们不妨以 \(r\) 为根将原先的无根树变成一棵有根树,那么有一个性质:对于任何 \(v\) 是 \(u\) 的祖先均有 \(d_v\ge d_u\)。证明:首先假设一条树的直径为 \(x,y\),我们先证明一个引理:对于任意节点 \(t\ne u\),记 \(ind_t\) 为使 \(\text{dist}(t,v)\) 取到最大值的 \(v\),那么 \(ind_t\) 一定不在 \(t\) 的子树中,考虑反证法,假设 \(ind_t\) 在 \(t\) 的子树中,那么一定有 \(d_r\ge \text{dist}(r,ind_t))>\text{dist}(t,ind_t)=d_t\),不符合 \(d_r\) 最小的条件,矛盾。显然原命题等价于对于所有 \(u\) 及其父亲 \(f\) 都有 \(d_f\le d_u\),考虑某个点 \(u\) 及其父亲 \(f\),若 \(f\ne r\),由于 \(ind_u\) 不在 \(u\) 的子树中,必然有 \(\text{dist}(ind_u,u)=\text{dist}(ind_u,f)+\text{dist}(u,f)\),又由于 \(ind_f\) 不在 \(f\) 的子树中,必然也有 \(ind_f\) 不在 \(u\) 的子树中,因此 \(\text{dist}(ind_u,f)=d_f\),又由于 \(\text(dist)(u,f)>0\),故 \(d_f<d_u\),否则由 \(d_r\) 为最小的 \(d_i\) 可知命题显然成立。
有了这个性质,我们可以用 two-pointers 的方法,枚举连通块中最小的 \(d_u\),并 two pointers 维护所有 \(d_u\le d_v\le d_u+l\) 的 \(v\),根据上面的推论在这样的 \(v\) 组成的子图中,\(u\) 所在的连通块必定是以 \(u\) 为根的一个虚树,并查集即可,虽然这里需要支持删点,看上去不太可做,不过显然删除的点并不会影响连通性,用并查集维护联通块大小是正确的。
时间复杂度 \(n\log n+qn\alpha(n)\)。
const int MAXN=1e5;
int n,hd[MAXN+5],to[MAXN*2+5],nxt[MAXN*2+5],val[MAXN*2+5],ec=0;
void adde(int u,int v,int w){to[++ec]=v;val[ec]=w;nxt[ec]=hd[u];hd[u]=ec;}
ll dis[MAXN+5],d[MAXN+5];
void dfs(int x,int f){
chkmax(d[x],dis[x]);
for(int e=hd[x];e;e=nxt[e]){
int y=to[e],z=val[e];if(y==f) continue;
dis[y]=dis[x]+z;dfs(y,x);
}
} int ord[MAXN+5],fa[MAXN+5];
void getfa(int x,int f){
fa[x]=f;
for(int e=hd[x];e;e=nxt[e]){
int y=to[e];if(y==f) continue;
getfa(y,x);
}
}
bool cmp(int x,int y){return d[x]<d[y];}
int f[MAXN+5],siz[MAXN+5];
int find(int x){return (!f[x])?x:f[x]=find(f[x]);}
void merge(int x,int y){x=find(x);y=find(y);if(x^y) f[x]=y,siz[y]+=siz[x];}
int main(){
scanf("%d",&n);
for(int i=1,u,v,w;i<n;i++){
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);adde(v,u,w);
} dfs(1,0);int rt=0;
for(int i=1;i<=n;i++) if(dis[i]>dis[rt]) rt=i;
dis[rt]=0;dfs(rt,0);rt=0;
for(int i=1;i<=n;i++) if(dis[i]>dis[rt]) rt=i;
dis[rt]=0;dfs(rt,0);for(int i=1;i<=n;i++) ord[i]=i;
sort(ord+1,ord+n+1,cmp);getfa(ord[1],0);
// for(int i=1;i<=n;i++) printf("%lld%c",d[i],(i==n)?'\n':' ');
// for(int i=1;i<=n;i++) printf("%d%c",ord[i],(i==n)?'\n':' ');
// for(int i=1;i<=n;i++) printf("%d%c",fa[i],(i==n)?'\n':' ');
int qu;scanf("%d",&qu);
while(qu--){
ll l;int ans=0;scanf("%lld",&l);
for(int i=1;i<=n;i++) f[i]=0,siz[i]=1;
for(int i=n,j=n;i;i--){
while(d[ord[j]]>d[ord[i]]+l) siz[find(ord[j])]--,j--;
// printf("%d %d %d\n",i,j,siz[find(ord[i])]);
chkmax(ans,siz[find(ord[i])]);if(fa[ord[i]]) merge(ord[i],fa[ord[i]]);
} printf("%d\n",ans);
}
return 0;
}
Codeforces 516D - Drazil and Morning Exercise(树的直径+并查集)的更多相关文章
- 【loj6038】「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目描述 给你 $n$ 个点,支持 $m$ 次操作,每次为以下两种:连一条边,保证连完后是一棵树/森林:询问一个点能到达的最远的点与该点的距离.强制在线. $n\le 3\times 10^5$ ,$ ...
- 【bzoj2870】最长道路tree 树的直径+并查集
题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...
- Codeforces 455C Civilization:树的直径 + 并查集【合并树后直径最小】
题目链接:http://codeforces.com/problemset/problem/455/C 题意: 给你一个森林,n个点,m条边. 然后有t个操作.共有两种操作: (1)1 x: 输出节点 ...
- 求树的直径+并查集(bfs,dfs都可以)hdu4514
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4514 这题主要是叫我们求出树的直径,在求树的直径之前要先判断一下有没有环 树的直径指的就是一棵树上面距 ...
- hdu 4514(树的直径+并查集)
湫湫系列故事——设计风景线 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...
- loj6038「雅礼集训 2017 Day5」远行 树的直径+并查集+LCT
题目传送门 https://loj.ac/problem/6038 题解 根据树的直径的两个性质: 距离树上一个点最远的点一定是任意一条直径的一个端点. 两个联通块的并的直径是各自的联通块的两条直径的 ...
- Codeforces 437D The Child and Zoo - 树分治 - 贪心 - 并查集 - 最大生成树
Of course our child likes walking in a zoo. The zoo has n areas, that are numbered from 1 to n. The ...
- BZOJ 2870: 最长道路tree 树的直径+并查集
挺好的一道题. 把所有点都离线下来,一个个往里加入就行了. #include <cstdio> #include <algorithm> #define N 100003 #d ...
- [BZOJ3038]上帝造题的七分钟2 树状数组+并查集
考试的时候用了两个树状数组去优化,暴力修改,树状数组维护修改后区间差值还有最终求和,最后骗了40分.. 这道题有好多种做法,求和好说,最主要的是开方.这道题过的关键就是掌握一点:在数据范围内,最多开方 ...
随机推荐
- Jmeter之BeanShell 断言
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15436864.html 博客主页:https://www.cnblogs.com/testero ...
- 基于JWT的Token身份验证
身份验证,是指通过一定的手段,完成对用户身份的确认.为了及时的识别发送请求的用户身份,我们调研了常见的几种认证方式,cookie.session和token. 1.Cookie cookie是 ...
- [对对子队]会议记录4.10(Scrum Meeting 1)
本次每日例会的开会时间是4月10日晚上20:00,使用腾讯会议作为开会工具. 今天已完成的工作 何瑞 工作内容:制作UI界面的指令编辑系统,已大致实现指令的衔接 相关issue:实现用户指令编 ...
- Spring动态添加定时任务
Spring动态添加定时任务 一.背景 二.需求和实现思路 1.能够动态的添加一个定时任务. 2.能够取消定时任务的执行. 3.动态的修改任务执行的时间. 4.获取定时任务执行的异常 三.代码实现 四 ...
- Spring Cloud Gateway Route Predicate Factory 的使用
Spring Cloud Gateway的使用 一.需求 二.基本组成 1.简介 2.核型概念 1.Route 路由 2.Predicate 谓语.断言 3.Filter 过滤器 3.工作原理 三.网 ...
- Stack2 攻防世界题目分析
---XCTF 4th-QCTF-2018 前言,怎么说呢,这题目还是把我折磨的可以的,我一开始是没有看到后面的直接狙击的,只能说呢. 我的不经意间的粗心,破坏了你许多的温柔 1.气的我直接检查保护: ...
- js 原型链详解
目录 构造函数和实例 属性Prototype 属性__proto__ 访问原型上的方法 构造函数也有__proto__ 构造函数的原型也有__proto__ Object.prototype这个原型对 ...
- 公众号H5页面接入微信登录流程
公众号H5页面接入微信登录流程 源码地址 https://gitee.com/szxio/h5_weixin 起步 首先创建一个项目,我们采用uni-app来作为我们的前端框架 环境安装 全局安装vu ...
- 【代码更新】单细胞分析实录(20): 将多个样本的CNV定位到染色体臂,并画热图
之前写过三篇和CNV相关的帖子,如果你做肿瘤单细胞转录组,大概率看过: 单细胞分析实录(11): inferCNV的基本用法 单细胞分析实录(12): 如何推断肿瘤细胞 单细胞分析实录(13): in ...
- seq2seq之双向解码
目录 背景介绍 双向解码 基本思路 数学描述 模型实现 训练方案 双向束搜索 代码参考 思考分析 文章小结 在文章<玩转Keras之seq2seq自动生成标题>中我们已经基本探讨过seq2 ...