HiHoCoder1156 彩色的树(树值的记忆化ORZ+map强势出场)
1156 : 彩色的树
描述
给定一棵n个节点的树,节点编号为1, 2, …, n。树中有n - 1条边,任意两个节点间恰好有一条路径。这是一棵彩色的树,每个节点恰好可以染一种颜色。初始时,所有节点的颜色都为0。现在需要实现两种操作:
1. 改变节点x的颜色为y;
2. 询问整棵树被划分成了多少棵颜色相同的子树。即每棵子树内的节点颜色都相同,而相邻子树的颜色不同。
输入
第一行一个整数T,表示数据组数,以下是T组数据。
每组数据第一行是n,表示树的节点个数。接下来n - 1行每行两个数i和j,表示节点i和j间有一条边。接下来是一个数q,表示操作数。之后q行,每行表示以下两种操作之一:
1. 若为"1",则询问划分的子树个数。
2. 若为"2 x y",则将节点x的颜色改为y。
输出
每组数据的第一行为"Case #X:",X为测试数据编号,从1开始。
接下来的每一行,对于每一个询问,输出一个整数,为划分成的子树个数。
数据范围
1 ≤ T ≤ 20
0 ≤ y ≤ 100000
小数据
1 ≤ n, q ≤ 5000
大数据
1 ≤ n, q ≤ 100000
- 样例输入
-
2
3
1 2
2 3
3
1
2 2 1
1
5
1 2
2 3
2 4
2 5
4
1
2 2 1
2 3 2
1 - 样例输出
-
Case #1:
1
3
Case #2:
1
5
由于无环,和断点(改变颜色的点)连接的点如果颜色和改变前一样,树++。和改变后一样树--。
代码一号,树上乱搞:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn],cnt;
int ans,V[maxn];void add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
}
void init()
{
ans=;cnt=;
memset(Laxt,,sizeof(Laxt));
memset(V,,sizeof(V));
}
void change(int x,int y)
{
bool flag=false;
int tmp=;
for(int i=Laxt[x];i;i=Next[i]){
if(V[To[i]]==y) ans--;
if(V[To[i]]==V[x]) ans++;
}
V[x]=y;
}
int main()
{
int T,n,i,j,x,y,q,u,v,Case=;
scanf("%d",&T);
while(T--){
printf("Case #%d:\n",++Case);
init();
scanf("%d",&n);
for(i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
scanf("%d",&q);
while(q--){
scanf("%d",&x);
if(x==) printf("%d\n",ans);
else {
scanf("%d%d",&x,&y);
change(x,y);
}
}
}
return ;
}
每次访问邻边导致耗时过多。怎么记录?
首先,无向图变有向图,==其实就是父子关系辣。
一个节点记录相邻儿子的信息。如果改变某点,就只改变它父亲的信息就ok。
强势之处:
通过父子关系使记录和查询变成O(1),访问效率高;
map记录每个节点的有效颜色,空间利用效率高。
代码二号:
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn<<],To[maxn<<],cnt;
int ans,V[maxn],fa[maxn];
map<int,int>G[maxn];
void add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
}
void init()
{
ans=;cnt=;
memset(Laxt,,sizeof(Laxt));
memset(V,,sizeof(V));
}
void change(int x,int y)
{
if(V[x]==y) return ;
ans+=G[x][V[x]];
ans-=G[x][y];
if(fa[x]!=){
if(V[fa[x]]==V[x]) ans++;
if(V[fa[x]]==y) ans--;
G[fa[x]][V[x]]--;
G[fa[x]][y]++;
}
V[x]=y;
}
void dfs(int u,int pre)
{
fa[u]=pre;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]==pre) continue;
G[u][]++;
dfs(To[i],u);
}
}
int main()
{
int T,n,i,x,y,q,Case=;
scanf("%d",&T);
while(T--){
printf("Case #%d:\n",++Case);
init();
scanf("%d",&n);
for(i=;i<=n;i++) G[i].clear();
for(i=;i<n;i++){
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
dfs(,);
scanf("%d",&q);
while(q--){
scanf("%d",&x);
if(x==) printf("%d\n",ans);
else {
scanf("%d%d",&x,&y);
change(x,y);
}
}
}
return ;
}
HiHoCoder1156 彩色的树(树值的记忆化ORZ+map强势出场)的更多相关文章
- ZOJ 3644 Kitty's Game dfs,记忆化搜索,map映射 难度:2
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834 从点1出发,假设现在在i,点数为sta,则下一步的点数必然不能是sta的 ...
- P1040 加分二叉树(树上记忆化搜素)
这道题很水 但我没做出来……………………………… 我写的时候状态设计错了,设计dp[l][m][r]为从l到r以m为根的值 这样写遍历状态就是n^3的,会TLE. 而且写路径的时候是用结构体写的,这样 ...
- 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索
题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...
- 洛谷 2921 记忆化搜索 tarjan 基环外向树
洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...
- [HNOI2004]L语言 字典树 记忆化搜索
[HNOI2004]L语言 字典树 记忆化搜索 给出\(n\)个字符串作为字典,询问\(m\)个字符串,求每个字符串最远能匹配(字典中的字符串)到的位置 容易想到使用字典树维护字典,然后又发现不能每步 ...
- 洛谷P3960 列队 NOIp2017 线段树/树状数组/splay
正解:动态开点线段树 解题报告: 传送门! 因为最近学主席树的时候顺便get到了动态开点线段树?刚好想起来很久很久以前就想做结果一直麻油做的这题,,,所以就做下好了QAQ 然后说下,这题有很多种方法, ...
- 算法笔记--树的直径 && 树形dp && 虚树 && 树分治 && 树上差分 && 树链剖分
树的直径: 利用了树的直径的一个性质:距某个点最远的叶子节点一定是树的某一条直径的端点. 先从任意一顶点a出发,bfs找到离它最远的一个叶子顶点b,然后再从b出发bfs找到离b最远的顶点c,那么b和c ...
- CF487E Tourists 【圆方树 + 树剖 + 堆】
题目链接 CF487E 题解 圆方树 + 树剖 裸题 建好圆方树维护路径上最小值即可 方点的值为其儿子的最小值,这个用堆维护 为什么只维护儿子?因为这样修改点的时候就只需要修改其父亲的堆 这样充分利用 ...
- 【BZOJ3589】动态树 树链剖分+线段树
Description 别忘了这是一棵动态树, 每时每刻都是动态的. 小明要求你在这棵树上维护两种事件 事件0: 这棵树长出了一些果子, 即某个子树中的每个节点都会长出K个果子. 事件1: 小明希望你 ...
随机推荐
- XML约束技术
为了使XML文档规范化,对XML文档的书写进行约束 XML DTD XML文档(test.xml) <?xml version="1.0" encoding="ut ...
- React-Navigation与Redux整合详解
本文转自:文章地址:http://blog.csdn.net/u013718120/article/details/72357698 继react-navigation发布已经过去半年的时间,想必Re ...
- 伸展树基础(Splay)
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3948 Solved: 1627 [Submit][St ...
- HDU 1337 && POJ 1218&& zju 1350 方法总结
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1337 杭电 http://poj.org/problem?id=1218清华 http://acm.zj ...
- Aware接口
Aware接口: 例如: BeanNameAware接口是为了让自身Bean能够感知到,获取到自身在Spring容器中的id属性. 同理,其他的Aware接口也是为了能够感知到自身的一些属性. 比如实 ...
- var与this定义变量的区别以及疑惑
我们知道: var可以定义一个局部变量,当然如果var定义在最外层的话,就是全局的局部变量,也就算是全局变量了. 而this关键字定义的变量准确的说应该算是成员变量.即定义的是调用对象的成员变量. 另 ...
- 读取和修改xml
如有一个xml文件DownData.xml,内容如下 <?xml version="1.0" standalone="yes"?> <Root ...
- AttributeError: module 'matplotlib' has no attribute 'verbose' (pycharm中使用matplotlib 2.2.0的坑)
AttributeError: module 'matplotlib' has no attribute 'verbose' 环境信息 本地系统:win10 本地开发环境:python(3.6.3), ...
- Minimum Window Substring, 包含子串的最小窗口,双指针
问题描述:给定字符串S,子串T,求S中包含T的最小窗口 Given a string S and a string T, find the minimum window in S which will ...
- D3.js学习笔记(二)——使用绑定在DOM上的数据
简单例子 在这个例子中,你将会使用D3.js来将数据绑定到DOM元素上.然后再使用D3.js利用绑定到DOM元素上的数据来更新网页. 在上一章中,我们以下面这个页面作为开始的: <!DOCTYP ...