codeforces 600E. Lomsat gelral 启发式合并

题目链接

给一颗树, 每个节点有初始的颜色值。 1为根节点。定义一个节点的值为, 它的子树中出现最多的颜色的值, 如果有多种颜色出现的次数相同, 那么值为所有颜色的值的和。

每一个叶子节点是一个map, 然后从叶子节点并上去, 注意并的时候把小的map并到大的map里面。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pb(x) push_back(x)
 4 #define ll long long
 5 #define mk(x, y) make_pair(x, y)
 6 #define lson l, m, rt<<1
 7 #define mem(a) memset(a, 0, sizeof(a))
 8 #define rson m+1, r, rt<<1|1
 9 #define mem1(a) memset(a, -1, sizeof(a))
10 #define mem2(a) memset(a, 0x3f, sizeof(a))
11 #define rep(i, a, n) for(int i = a; i<n; i++)
12 #define ull unsigned long long
13 typedef pair<int, int> pll;
14 const double PI = acos(-1.0);
15 const double eps = 1e-8;
16 const int mod = 1e9+7;
17 const int inf = 1061109567;
18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
19 const int maxn = 1e5+5;
20 int head[maxn*2], color[maxn], num, cnt[maxn], id[maxn];
21 ll anss[maxn], ans[maxn];
22 struct node
23 {
24     int to, nextt;
25 }e[maxn*2];
26 void add(int u, int v) {
27     e[num].to = v, e[num].nextt = head[u], head[u] = num++;
28 }
29 map <int, int> m[maxn];
30 void combine(int &u, int &v) {
31     if(m[u].size()<m[v].size())
32         swap(u, v);
33     for(auto it = m[v].begin(); it!=m[v].end(); it++) {
34         m[u][it->first] += it->second;
35         if(m[u][it->first]>cnt[u]) {
36             cnt[u] = m[u][it->first];
37             ans[u] = it->first;
38         } else if(m[u][it->first] == cnt[u]) {
39             ans[u] += it->first;
40         }
41     }
42 }
43 void dfs(int u, int fa) {
44     for(int i = head[u]; ~i; i = e[i].nextt) {
45         int v = e[i].to;
46         if(v == fa)
47             continue;
48         dfs(v, u);
49         combine(id[u], id[v]);
50     }
51     anss[u] = ans[id[u]];
52 }
53 int main()
54 {
55     mem1(head);
56     int n, x, y;
57     cin>>n;
58     for(int i = 1; i<=n; i++) {
59         scanf("%d", &x);
60         id[i] = i;
61         m[i][x] = 1;
62         cnt[i] = 1;
63         ans[i] = x;
64     }
65     for(int i = 0; i<n-1; i++) {
66         scanf("%d%d", &x, &y);
67         add(x, y);
68         add(y, x);
69     }
70     dfs(1, 0);
71     for(int i = 1; i<=n; i++) {
72         printf("%I64d ", anss[i]);
73     }
74     return 0;
75 }

 

posted on 2015-12-22 16:25  yohaha  阅读(413)  评论(0编辑  收藏  举报

导航