CF1009F Dominant Indices(启发式合并)
You are given a rooted undirected tree consisting of nn vertices. Vertex 11 is the root.
Let's denote a depth array of vertex xx as an infinite sequence [dx,0,dx,1,dx,2,…][dx,0,dx,1,dx,2,…], where dx,idx,i is the number of vertices yy such that both conditions hold:
- xx is an ancestor of yy;
- the simple path from xx to yy traverses exactly ii edges.
The dominant index of a depth array of vertex xx (or, shortly, the dominant index of vertex xx) is an index jj such that:
- for every k<jk<j, dx,k<dx,jdx,k<dx,j;
- for every k>jk>j, dx,k≤dx,jdx,k≤dx,j.
For every vertex in the tree calculate its dominant index.
Input
The first line contains one integer nn (1≤n≤1061≤n≤106) — the number of vertices in a tree.
Then n−1n−1 lines follow, each containing two integers xx and yy (1≤x,y≤n1≤x,y≤n, x≠yx≠y). This line denotes an edge of the tree.
It is guaranteed that these edges form a tree.
Output
Output nn numbers. ii-th number should be equal to the dominant index of vertex ii.
Examples
4
1 2
2 3
3 4
0
0
0
0
4
1 2
1 3
1 4
1
0
0
0
4
1 2
2 3
2 4
2
1
0
0
题解:题目意思为:给你一颗有根数,对于每一个节点,他的子树到他的边数为d,到达他的边数为d的数量为fd,让你求每一个节点fd最大的d,如果有多个选择d最小的那个;
用map<int,int> mp[i][d]:表示节点I的子树中的节点中深度为d(表示到根节点的边数)的数量。然后沿着重边一直往下搜索,启发式搜索,每次更新ans[u]即可;
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define clr(a,val) memset(a,val,sizeof(a))
#define pb push_back
#define fi first
#define se second
typedef long long ll;
const int maxn=1e6+;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
}
struct Edge{
int to,nxt;
} edge[maxn<<];
int n,cnt,dep[maxn],hvy[maxn],hson[maxn],head[maxn<<];
int maxd[maxn],ans[maxn];
map<int,int> mp[maxn];
inline void addedge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
inline void dfs1(int u,int fa)
{
hvy[u]=dep[u];
for(int e=head[u];~e;e=edge[e].nxt)
{
int v=edge[e].to;
if(v==fa) continue;
dep[v]=dep[u]+;
dfs1(v,u);
if(hvy[v]>hvy[u])
{
hson[u]=v;
hvy[u]=hvy[v];//子树的最深深度
}
}
}
inline void dfs2(int u,int fa)
{
for(int e=head[u];~e;e=edge[e].nxt)
{
int v=edge[e].to;
if(v==fa) continue;
dfs2(v,u);
}
if(hson[u]>)
{
int v=hson[u];
swap(mp[u],mp[v]);
mp[u][dep[u]]=;
if(maxd[v]>)
{
maxd[u]=maxd[v];
ans[u]=ans[v]+;
}
else maxd[u]=,ans[u]=;
}
else maxd[u]=,ans[u]=,mp[u][dep[u]]=;
map<int,int>::iterator it;
for(int i=head[u];~i;i=edge[i].nxt)
{
int v=edge[i].to;
if(v==fa || v==hson[u]) continue;
for(it=mp[v].begin();it!=mp[v].end();it++)
{
mp[u][(*it).fi]+=mp[v][(*it).fi];
if(mp[u][(*it).fi]>maxd[u])
{
maxd[u]=mp[u][(*it).fi];
ans[u]=(*it).fi-dep[u];
}
if(mp[u][(*it).fi]==maxd[u] && (*it).fi-dep[u]<ans[u]) ans[u]=(*it).fi-dep[u];
}
}
} int main()
{
n=read();int u,v;
cnt=;clr(head,-);
for(int i=;i<=n;++i) mp[i].clear();
for(int i=;i<n;++i)
{
u=read(),v=read();
addedge(u,v);addedge(v,u);
}
dep[]=;dfs1(,);dfs2(,);
for(int i=;i<=n;++i) printf("%d%c",ans[i],i==n? '\n':' ');
return ;
}
CF1009F Dominant Indices(启发式合并)的更多相关文章
- [CF1009F] Dominant Indices (+dsu on tree详解)
这道题用到了dsu(Disjoint Set Union) on tree,树上启发式合并. 先看了CF的官方英文题解,又看了看zwz大佬的题解,差不多理解了dsu on tree的算法. 但是时间复 ...
- CF1009F Dominant Indices 解题报告
CF1009F Dominant Indices 题意简述 给出一颗以\(1\)为跟的有根树,定义\(d_{i,j}\)为以\(i\)为根节点的子树中到\(i\)的距离恰好为\(j\)的点的个数,对每 ...
- CF1009F Dominant Indices
传送门 还是放个链接让泥萌去学一下把 orzYYB 题目中要求的\(f_{x,j}\),转移是\(f_{x,j}=\sum_{y=son_x} f_{y,j-1}\),所以这个东西可以用长链剖分优化, ...
- CF1009F Dominant Indices——长链剖分优化DP
原题链接 \(EDU\)出一道长链剖分优化\(dp\)裸题? 简化版题意 问你每个点的子树中与它距离为多少的点的数量最多,如果有多解,最小化距离 思路 方法1. 用\(dsu\ on\ tree\)做 ...
- CF1009F Dominant Indices(树上DSU/长链剖分)
题目大意: 就是给你一棵以1为根的树,询问每一个节点的子树内节点数最多的深度(相对于这个子树根而言)若有多解,输出最小的. 解题思路: 这道题用树链剖分,两种思路: 1.树上DSU 首先想一下最暴力的 ...
- CF1009F Dominant Indices 长链剖分
题目传送门 https://codeforces.com/contest/1009/problem/F 题解 长链剖分的板子吧. 令 \(dp[x][i]\) 表示 \(x\) 的子树中的深度为 \( ...
- Codeforces 1009 F. Dominant Indices(长链剖分/树上启发式合并)
F. Dominant Indices 题意: 给一颗无向树,根为1.对于每个节点,求其子树中,哪个距离下的节点数量最多.数量相同时,取较小的那个距离. 题目: 这类题一般的做法是树上的启发式合并,复 ...
- 【CF1009F】Dominant Indices(长链剖分)
[CF1009F]Dominant Indices(长链剖分) 题面 洛谷 CF 翻译: 给定一棵\(n\)个点,以\(1\)号点为根的有根树. 对于每个点,回答在它子树中, 假设距离它为\(d\)的 ...
- Codeforces 1009 F - Dominant Indices
F - Dominant Indices 思路:树上启发式合并 先跑轻子树,然后清除轻子树的信息 最后跑重子树,不清除信息 然后再跑一遍轻子树,重新加回轻子树的信息 由于一个节点到根节点最多有logn ...
随机推荐
- 瞎折腾实录:构建 Armel 版本的 .NET Core 教程和资料资源
目录 首先我要说明,我失败了~ 我把我的进度和经验放出来,希望能够帮助别人完成编译工作~ 背景:最近接手一个华为某型号的嵌入式设备,需要在上面搭建 .NET Core 环境. 设备是 Armel 架构 ...
- Jenkins集群下的pipeline实战
关于Jenkins集群 在<快速搭建Jenkins集群>一文中,我们借助docker快速搭建了Jenkins集群,今天就在这个集群环境中创建pipeline任务,体验Jenkins集群下的 ...
- maven的项目结构
1.标准目录结构: src -main –bin 脚本库 –java java源代码文件 –resources 资源库,会自动复制到classes目录里 ...
- springboot配置springMVC
/** * @ClassName MvcConfigure * @Description SpringMVC配置 * @Author JAGNG * @Date 2019/10/28 10:23 ** ...
- vue开发之跨域请求,请求头not allowed by Access-Control-Allow-Headers,后端cookie session值取不到(二)
原因:你本地的请求ajax的get和post请求:如果你的请求头内放一些可用验证数据Token的时候就会存在跨域请求这是浏览器所不允许的问题: 方案一:后台的接口请求模式都写成jsonp请求,前端去调 ...
- 1005 Spell It Right(20 分)
1005 Spell It Right(20 分) Given a non-negative integer N, your task is to compute the sum of all the ...
- 【前端知识体系-JS相关】JS-Web-API总结
2.1 DOM操作 2.1.1 DOM的本质是什么? <!-- DOM树:二叉树 --> /* <?xml version="1.0" encoding=&quo ...
- MySQL/MariaDB读写分离配置
DB读写分离描述 数据库的读写分离其实就是为了加减少数据库的压力:数据库的写入操作由主数据库来进行,读取操作由从数据库来进行操作.实现数据库读写分离技术是有很多方法的,在这里我就用一个比较简单的mys ...
- Nethunter开启ssh服务
### 本节用来纪念我和我的Nethunter SSH服务的血泪史 刚安装好Nethunter后,手机的各种功能也是令我眼花缭乱,对手机是爱不释手,可是,手机开启ssh服务之后,电脑无法连接,这就很尴 ...
- iOS 抽奖轮盘效果实现思路
临近活动,相信不少app都会加一个新的需求——抽奖不多废话,先上GIF效果图 作为一个开发者,有一个学习的氛围跟一个交流圈子特别重要这是一个我的iOS交流群:937194184,不管你是小白还是大牛欢 ...