Educational Codeforces Round 2 E. Lomsat gelral(启发式合并map)

来源:互联网 发布:www.gvlib video.php 编辑:程序博客网 时间:2024/06/06 04:02

题目链接
题意:给你一个树,然后每个节点有一个颜色,然后问你每个节点为子树的颜色出现最多的,权重和,权重是颜色值。
解法:把小的map合并到大的map里面,(新姿势),官方题解,说这个很有用耶
官方题解

#include<bits/stdc++.h>using namespace std;#define pb push_back#define LL long longconst int maxn=100002;const int inf=1<<28;vector<int> E[maxn*2];map<int,int> H[maxn];map<int,int>::iterator it;int color[maxn],id[maxn];LL cnt[maxn],ans[maxn],sum[maxn];void Merge(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(cnt[x]<H[x][it->first]){            cnt[x]=H[x][it->first];            ans[x]=it->first;        }        else if(cnt[x]==H[x][it->first]){            ans[x]+=it->first;        }    }}void dfs(int x,int fa) {    for(int i=0; i<E[x].size(); i++) {        if(E[x][i]==fa)continue;        dfs(E[x][i],x);        Merge(id[x],id[E[x][i]]);    }    sum[x]=ans[id[x]];}int main() {    int n;    scanf("%d",&n);    for(int i=1; i<=n; i++) {        scanf("%d",&color[i]);        id[i]=i;        H[i][color[i]]=1;        cnt[i]=1;        ans[i]=color[i];    }    for(int i=1; i<n; i++) {        int x,y;        scanf("%d%d",&x,&y);        E[x].pb(y);        E[y].pb(x);    }    dfs(1,-1);    for(int i=1;i<=n;i++){        printf("%lld ",sum[i]);    }    return 0;}
0 0
原创粉丝点击