hihoCoder #1156 : 彩色的树 2015编程之美初赛
来源:互联网 发布:银行风险预警模型数据 编辑:程序博客网 时间:2024/05/17 02:53
题意
- 给你一颗树,n个节点,每个节点有颜色,初始为0
- 有q次操作,操作1是查询这棵树的不同颜色的子树个数,2是修改某个点的颜色
思路
- 这题不是很难,因为每次修改只改一个点,而且从这个点我们就可以比较容易的得出当前这个状态下,全局的不同颜色子树的变化量。
- 具体来说,我们维护对每个节点记录它的父亲节点编号,维护它的颜色,和它孩子节点的颜色,把这些颜色记录在map中,即map[0]表示它颜色为0的孩子个数。
- 我们用ans记录当前的不同颜色子树数量
- 当修改一个点u时,我们很容易找到,原来u和父亲节点以及孩子节点不同颜色的数量记为tmp1,然后修改u的颜色,再计算上述内容记为tmp2,然后ans += tmp2 - tmp1
- 这题比较坑的是,树的边它不一定按照真实方向给出。。。所以必须先定一下方向。。这点坑了我半天。。。
- 然后是,注意这题要用平衡二叉搜索树的map,用而不能用hash的unordered_map,否则会T,我猜测原因是,每个节点都要维护map,所以可能其记录的值很少,所以用hash的话冲突发生的概率比较大。。所以T了,而map则复杂度稳定
实现
#include <iostream>#include <cstring>#include <cstdio>#include <vector>#include <queue>#include <map>using namespace std;const int maxn = 100005;#define pb push_backstruct Node{ int col,fa,chld_num; map<int,int> child_col; vector<int> child; Node(){ col = 0; fa = 0; chld_num = 0; } void clear() { col = 0; fa = 0; chld_num = 0; child_col.clear(); child.clear(); }}node[maxn];int cal(int id){ int ret = 0; int fa = node[id].fa; if (fa != 0 && node[id].col != node[fa].col){ ret++; } ret += node[id].chld_num - node[id].child_col[node[id].col]; return ret;}int mark[maxn];queue<int> q;void bfs(){ node[1].fa = 0; node[1].chld_num = node[1].child.size(); node[1].child_col[0] = node[1].chld_num; mark[1] = 1; q.push(1); while (q.size() > 0){ int u = q.front(); q.pop(); for (int i=0;i<node[u].child.size();i++){ int j = node[u].child[i]; if (mark[j]){ continue; } mark[j] = 1; node[j].fa = u; node[j].chld_num = node[j].child.size() - 1; node[j].child_col[0] = node[j].chld_num; q.push(j); } }}int main(){ int T; int n,q; scanf("%d",&T); for (int t= 1; t<=T;t++){ printf("Case #%d:\n",t); scanf("%d",&n); memset(mark,0,sizeof(mark)); for (int i=1;i<=n;i++) node[i].clear(); for (int i=0;i<n-1;i++){ int u,v; scanf("%d%d",&u,&v); node[u].child.pb(v); node[v].child.pb(u); } bfs(); scanf("%d",&q); int ans = 1; for (int qq=0;qq<q;qq++){ int tmp,col; scanf("%d",&tmp); if (tmp == 1){ printf("%d\n",ans); continue; } scanf("%d%d",&tmp,&col); ans -= cal(tmp); if (node[tmp].fa != 0){ node[node[tmp].fa].child_col[node[tmp].col]--; node[node[tmp].fa].child_col[col]++; } node[tmp].col = col; ans += cal(tmp); } } return 0;}
0 0
- hihoCoder #1156 : 彩色的树 2015编程之美初赛
- hihoCoder 1156 彩色的树 编程之美2015初赛第一场
- 2015编程之美初赛第一场 A 彩色的树
- hihoCoder 1159 扑克牌 编程之美2015初赛第二场
- hihoCoder 1160 攻城略地 编程之美2015初赛第二场
- 2015编程之美 彩色的树
- 2015编程之美 彩色的树
- hihoCoder 1161 八卦的小冰 编程之美2015初赛第二场
- 编程之美15-彩色的树
- 编程之美 彩色的树
- 2015编程之美初赛
- 2015 编程之美彩色的树A
- hihoCoder 1156 彩色的树
- hihocoder 1156 彩色的树
- 编程之美2015初赛A
- 【编程之美】初赛2015 待填坑
- 2015编程之美挑战赛初赛题目
- 编程之美初赛第一场 树
- web.xml中的welcome-file-list
- 九九乘法表
- css中各种居中总结
- 简单选择排序和二元选择排序的代码实现
- HTML5开发手机项目-总括
- hihoCoder #1156 : 彩色的树 2015编程之美初赛
- 蓝懿 ios技术交流和心得分享12.29
- 使用dbms_logmnr查看日志文件
- Xamarin Mono For Android、Monotouch 安装、破解
- VB Webbrowser控件如何屏蔽右键
- UIButton
- 克鲁斯卡尔算法
- 太上感应篇0004
- 【Opencv学习笔记】7.2霍夫变换