zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 2 E. Lomsat gelral 启发式合并map

    E. Lomsat gelral

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/contest/600/problem/E

    Description

    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.

    Sample Input

    4
    1 2 3 4
    1 2
    2 3
    2 4

    Sample Output

    10 9 3 4

    HINT

    题意

    给你一棵树,告诉你每个节点的颜色,然后让你输出对于这个节点的子树中,出现次数最多的颜色的权值和是多少

    题解:

    启发式合并map

    对于每一个子树,我们都维护一个map,然后从小的合并到大的中

    均摊下来复杂度不会很高(雾

    代码:

    #include<iostream>
    #include<stdio.h>
    #include<vector>
    #include<map>
    using namespace std;
    #define maxn 800005
    
    
    map<int,int> H[maxn];
    map<int,int>::iterator it;
    long long ans[maxn];
    vector<int> E[maxn];
    int c[maxn];
    int id[maxn];
    long long M[maxn];
    long long M1[maxn];
    void uni(int &x,int y)
    {
        if(H[x].size()<H[y].size())swap(x,y);
        for(it = H[y].begin();it!=H[y].end();it++)
        {
            H[x][it->first]+=it->second;
            if(M1[x]==H[x][it->first])
                M[x]+=it->first;
            if(M1[x]<H[x][it->first])
            {
                M1[x]=H[x][it->first];
                M[x]=it->first;
            }
        }
    }
    void solve(int x,int fa)
    {
        H[x][c[x]]=1;
        M1[x]=1,M[x]=c[x];
        for(int i=0;i<E[x].size();i++)
        {
            if(E[x][i]==fa)continue;
            solve(E[x][i],x);
            uni(id[x],id[E[x][i]]);
        }
        ans[x]=M[id[x]];
    }
    long long flag = 0;
    int main()
    {
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            id[i]=i;
            scanf("%d",&c[i]);
        }
        for(int i=1;i<n;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            E[x].push_back(y);
            E[y].push_back(x);
        }
        solve(1,-1);
        for(int i=1;i<=n;i++)
            printf("%lld ",ans[i]);
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    Markdown
    异异还原
    程序和算法
    运算符
    Java复习1
    复习总结
    为什么Byte是8位,但是却只能表示到127,而不是255?
    笔记的认识
    笔记本触摸板
    电脑热键
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5005628.html
Copyright © 2011-2022 走看看