zoukankan      html  css  js  c++  java
  • codeforces600E. Lomsat gelral(dsu on tree)

    You are given a rooted tree with root in vertex 1. Each vertex is coloured in some colour.
    Let’s call colour c dominating in the subtree of vertex v if there are no other colours that appear in the subtree of vertex v more times than colour c. So it’s possible that two or more colours will be dominating in the subtree of some vertex.
    The subtree of vertex v is the vertex v and all other vertices that contains vertex v in each path to the root.
    For each vertex v find the sum of all dominating colours in the subtree of vertex v.

    Input
    The first line contains integer n (1 ≤ n ≤ 105) — the number of vertices in the tree.
    The second line contains n integers ci (1 ≤ ci ≤ n), ci — the colour of the i-th vertex.
    Each of the next n - 1 lines contains two integers xj, yj (1 ≤ xj, yj ≤ n) — the edge of the tree. The first vertex is the root of the tree.

    Output
    Print n integers — the sums of dominating colours for each vertex.

    Examples
    input
    4
    1 2 3 4
    1 2
    2 3
    2 4

    output
    10 9 3 4

    input
    15
    1 2 3 1 2 3 3 1 1 3 2 2 1 2 3
    1 2
    1 3
    1 4
    1 14
    1 15
    2 5
    2 6
    2 7
    3 8
    3 9
    3 10
    4 11
    4 12
    4 13

    output
    6 5 4 3 2 3 3 1 1 3 2 2 1 2 3

    分析:
    我这个zz不看题
    被yveh学长嘲讽。。。
    首先读懂题目,
    我们需要统计的是以i为根节点的子树中
    数目最多的颜色的权值和是多少
    (就是按出现频率排序,排第一的一种或几种颜色分别是什么,把颜色编号加起来输出)

    显然这样一遍dfs是不可能的了
    n^2暴力太不优美

    我们就需要学习一种新的数据结构:dsu on tree

    推荐学长良心blog
    http://blog.csdn.net/qaq__qaq/article/details/53455462

    主体思路也是轻重链剖分
    但是没有那么繁琐了,不用维护太多东西
    首先找到每个节点的重儿子
    之后再进行一遍dfs

    dfs流程:
    1.dfs轻儿子
    2.dfs重儿子
    3.把儿子的信息记录到父亲
    4.Son=0
    5.记录答案
    6.一键消除轻儿子影响

    这里写代码片
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define ll long long
    
    using namespace std;
    
    const int N=100010;
    struct node{
        int x,y,nxt;
    };
    node way[N<<1];
    int st[N],n,tot=0,son[N],size[N],Son,mxx,cnt[N],c[N];
    ll sum,ans[N];
    
    void add(int u,int w)
    {
        tot++;
        way[tot].x=u;way[tot].y=w;way[tot].nxt=st[u];st[u]=tot;
        tot++;
        way[tot].x=w;way[tot].y=u;way[tot].nxt=st[w];st[w]=tot;
    }
    
    void js(int now,int fa,int v)
    {
        cnt[c[now]]+=v;  //now在子树中出现了几次 
        if (cnt[c[now]]>mxx) sum=(ll)c[now],mxx=cnt[c[now]];
        else if (cnt[c[now]]==mxx) sum+=(ll)c[now];
        for (int i=st[now];i;i=way[i].nxt)
            if (way[i].y!=fa&&way[i].y!=Son) js(way[i].y,now,v);  //way[i].y!=Son 
    }
    
    void getson(int now,int fa)
    {
        int i,mx=0;
        size[now]=1;
        for (i=st[now];i;i=way[i].nxt)
            if (way[i].y!=fa)
            {
                getson(way[i].y,now);
                size[now]+=size[way[i].y];
                if (size[way[i].y]>mx)
                {
                    mx=size[way[i].y];
                    son[now]=way[i].y;
                }
            }
    }
    
    void dfs(int now,int fa,int keep)  //keep用来标记是否要清除影响 
    {
        int i;
        for (i=st[now];i;i=way[i].nxt)
            if (way[i].y!=fa&&way[i].y!=son[now])
                dfs(way[i].y,now,0);   //轻儿子
        if (son[now]) dfs(son[now],now,1),Son=son[now];   //不清除影响
        js(now,fa,1);  //加入影响
        Son=0;   //进行到这一步,重儿子的信息一定已经计入了,这就说明整个子树都进行了统计 
        ans[now]=sum;   //记录答案
        if (!keep) js(now,fa,-1),mxx=sum=0;  //
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&c[i]);
        for (int i=1;i<n;i++)
        {
            int u,w;
            scanf("%d%d",&u,&w);
            add(u,w); 
        }
        getson(1,0); 
        dfs(1,1,0);
        for (int i=1;i<=n;i++) printf("%I64d ",ans[i]);
        return 0;
    } 
  • 相关阅读:
    java开发——Cloneable接口、clone()方法和深浅拷贝
    intellij idea 显示Arraylist 扩容过程 解决not showing null elements
    ArrayList的扩容方式和扩容时机
    【laravel5.4】发送alisms短信和163邮箱
    【laravel5.4】重定向带参数
    【laravel5.4】vue分页删除
    【laravel5.4】Baum无限极分类和collect助手函数、transform()中间件(转换数据)方法使用
    【laravel5.4】使用baum ode 类库实现无限极分类
    【VUE+laravel5.4】vue给http请求 添加请求头数据
    【laravel5.4】关键字【use】使用
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673392.html
Copyright © 2011-2022 走看看