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]即可;
参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define clr(a,val) memset(a,val,sizeof(a)) 4 #define pb push_back 5 #define fi first 6 #define se second 7 typedef long long ll; 8 const int maxn=1e6+10; 9 inline int read() 10 { 11 int x=0,f=1;char ch=getchar(); 12 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 13 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();} 14 return x*f; 15 } 16 struct Edge{ 17 int to,nxt; 18 } edge[maxn<<1]; 19 int n,cnt,dep[maxn],hvy[maxn],hson[maxn],head[maxn<<1]; 20 int maxd[maxn],ans[maxn]; 21 map<int,int> mp[maxn]; 22 inline void addedge(int u,int v) 23 { 24 edge[cnt].to=v; 25 edge[cnt].nxt=head[u]; 26 head[u]=cnt++; 27 } 28 inline void dfs1(int u,int fa) 29 { 30 hvy[u]=dep[u]; 31 for(int e=head[u];~e;e=edge[e].nxt) 32 { 33 int v=edge[e].to; 34 if(v==fa) continue; 35 dep[v]=dep[u]+1; 36 dfs1(v,u); 37 if(hvy[v]>hvy[u]) 38 { 39 hson[u]=v; 40 hvy[u]=hvy[v];//子树的最深深度 41 } 42 } 43 } 44 inline void dfs2(int u,int fa) 45 { 46 for(int e=head[u];~e;e=edge[e].nxt) 47 { 48 int v=edge[e].to; 49 if(v==fa) continue; 50 dfs2(v,u); 51 } 52 if(hson[u]>0) 53 { 54 int v=hson[u]; 55 swap(mp[u],mp[v]); 56 mp[u][dep[u]]=1; 57 if(maxd[v]>1) 58 { 59 maxd[u]=maxd[v]; 60 ans[u]=ans[v]+1; 61 } 62 else maxd[u]=1,ans[u]=0; 63 } 64 else maxd[u]=1,ans[u]=0,mp[u][dep[u]]=1; 65 map<int,int>::iterator it; 66 for(int i=head[u];~i;i=edge[i].nxt) 67 { 68 int v=edge[i].to; 69 if(v==fa || v==hson[u]) continue; 70 for(it=mp[v].begin();it!=mp[v].end();it++) 71 { 72 mp[u][(*it).fi]+=mp[v][(*it).fi]; 73 if(mp[u][(*it).fi]>maxd[u]) 74 { 75 maxd[u]=mp[u][(*it).fi]; 76 ans[u]=(*it).fi-dep[u]; 77 } 78 if(mp[u][(*it).fi]==maxd[u] && (*it).fi-dep[u]<ans[u]) ans[u]=(*it).fi-dep[u]; 79 } 80 } 81 } 82 83 84 int main() 85 { 86 n=read();int u,v; 87 cnt=0;clr(head,-1); 88 for(int i=0;i<=n;++i) mp[i].clear(); 89 for(int i=1;i<n;++i) 90 { 91 u=read(),v=read(); 92 addedge(u,v);addedge(v,u); 93 } 94 dep[1]=1;dfs1(1,0);dfs2(1,0); 95 for(int i=1;i<=n;++i) printf("%d%c",ans[i],i==n? '\n':' '); 96 return 0; 97 }