Educational Codeforces Round 2 E.Lomsat gelral(树形dp)
2016-01-18 20:53
477 查看
Educational Codeforces Round 2E:http://codeforces.com/contest/600/problem/E
E. Lomsat gelral
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 test(s)
input
output
input
output
题目大意:给定一颗树,节点i的控制颜色为包括该节点在内的所有子树节点中颜色出现最多的(可能有多个控制颜色),求每个节点控制颜色之和
大致思路:从叶子节点向上更新控制颜色即可,但是必须用map映射而且要将小树合并到大树当中,否则会MLE
E. Lomsat gelral
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
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 test(s)
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
题目大意:给定一颗树,节点i的控制颜色为包括该节点在内的所有子树节点中颜色出现最多的(可能有多个控制颜色),求每个节点控制颜色之和
大致思路:从叶子节点向上更新控制颜色即可,但是必须用map映射而且要将小树合并到大树当中,否则会MLE
#include <cstdio> #include <cstring> #include <vector> #include <map> #include <algorithm> using namespace std; int n,c[100005],index[100005],mx[100005];//c[i]表示i节点的颜色,index[i]表示i节点所对应的cnt下标,mx[index[i]]表示i节点相同颜色出现最多的次数 long long ans[100005],tmp[100005];//tmp[index[i]]表示i节点当前控制颜色总和 map<int,int> cnt[100005];//cnt[index[i]]表示i节点cnt[index[i]].first出现的次数为cnt[index[i]].second vector<int> v[100005]; void Merge(int s,int e) { if(cnt[index[s]].size()<cnt[index[e]].size())//总是将小树合并到大树上,以防MLE swap(index[s],index[e]); for(map<int,int>::iterator it=cnt[index[e]].begin();it!=cnt[index[e]].end();++it) {//枚举小树的map cnt[index[s]][it->first]+=it->second;//i节点中颜色it->first出现次数加it-second if(cnt[index[s]][it->first]>mx[index[s]]) {//如果当前颜色it->first出现次数已大于控制颜色出现次数 mx[index[s]]=cnt[index[s]][it->first];//更新控制线色出现次数 tmp[index[s]]=it->first;//重置控制颜色 } else if(cnt[index[s]][it->first]==mx[index[s]])//如果当前颜色it->first出现次数等于控制颜色出现次数 tmp[index[s]]+=it->first;//控制颜色加上当前颜色 } } void dfs(int pre,int u) { for(int i=0;i<v[u].size();++i) if(v[u][i]!=pre) { dfs(u,v[u][i]); Merge(u,v[u][i]); } ans[u]=tmp[index[u]]; } int main() { int s,e,i; while(1==scanf("%d",&n)) { for(i=1;i<=n;++i) { scanf("%d",c+i); index[i]=i; mx[i]=cnt[i][c[i]]=1; tmp[i]=c[i]; } for(i=1;i<n;++i) { scanf("%d%d",&s,&e); v[s].push_back(e); v[e].push_back(s); } dfs(1,1); for(i=1;i<n;++i) printf("%I64d ",ans[i]); printf("%I64d\n",ans ); } return 0; }
相关文章推荐
- JavaWeb学习总结(五十三)——Web应用中使用JavaMail发送邮件
- Kali Linux 安装教程-转
- iOS FMDB数据库加密相关
- SC命令---安装、开启、配置、关闭windows服务 bat批处理
- JavaWeb学习总结(五十二)——使用JavaMail创建邮件和发送邮件
- JavaWeb学习总结(五十一)——邮件的发送与接收原理
- 数据库不能open下查看undo段的名字
- 数组中常用算法(方法)总结
- java设计模式之享元模式
- 回首Hibernate之入门篇
- JavaWeb学习总结(四十九)——简单模拟Sping MVC
- Oracle定时计划快速使用
- Oracle定时计划快速使用
- Postgresql 正则表达式(转)
- linux删除指定行&删除行首空格&替换字符
- 指针变量 初级
- JavaWeb学习总结(四十八)——模拟Servlet3.0使用注解的方式配置Servlet
- 职责链+策略模式+外观实现用户下机
- CoreText实现图文混排
- javaweb学习总结(四十七)——监听器(Listener)在开发中的应用