• 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,kdx,jdx,k≤dx,j.

    For every vertex in the tree calculate its dominant index.

    Input

    The first line contains one integer nn (1n1061≤n≤106) — the number of vertices in a tree.

    Then n1n−1 lines follow, each containing two integers xx and yy (1x,yn1≤x,y≤n, xyx≠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

    Input
    4
    1 2
    2 3
    3 4
    Output
    0
    0
    0
    0
    Input
    4
    1 2
    1 3
    1 4
    Output
    1
    0
    0
    0
    Input
    4
    1 2
    2 3
    2 4
    Output
    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? '
    ':' ');
    96     return 0;
    97 }
    View Code
  • 相关阅读:
    每日总结4.25
    每日总结4.24
    每日总结4.23
    每日博客4.22
    每日博客4.21
    每日博客4.20
    每日总结4.19
    每日总结4.16
    每日总结4.15
    每日总结4.14
  • 原文地址:https://www.cnblogs.com/csushl/p/10293337.html
Copyright © 2020-2023  润新知