#1156 : 彩色的树


时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

给定一棵n个节点的树,节点编号为1, , …, n。树中有n - 1条边,任意两个节点间恰好有一条路径。这是一棵彩色的树,每个节点恰好可以染一种颜色。初始时,所有节点的颜色都为0。现在需要实现两种操作:

. 改变节点x的颜色为y;

. 询问整棵树被划分成了多少棵颜色相同的子树。即每棵子树内的节点颜色都相同,而相邻子树的颜色不同。

输入

第一行一个整数T,表示数据组数,以下是T组数据。

每组数据第一行是n,表示树的节点个数。接下来n - 1行每行两个数i和j,表示节点i和j间有一条边。接下来是一个数q,表示操作数。之后q行,每行表示以下两种操作之一:

. 若为"",则询问划分的子树个数。

. 若为"2 x y",则将节点x的颜色改为y。

输出

每组数据的第一行为"Case #X:",X为测试数据编号,从1开始。

接下来的每一行,对于每一个询问,输出一个整数,为划分成的子树个数。

数据范围

 ≤ T ≤ 

 ≤ y ≤ 

小数据

 ≤ n, q ≤ 

大数据

 ≤ n, q ≤ 
样例输入

样例输出
Case #:

Case #:

解题步骤:1、求出所有点的父结点,这边用的bfs遍历

              2、使用一个map<int,int>mp[N],mp[i][j]=k表示第i个结点的颜色是j,并且和它同颜色的儿子结点数为k

              3、ans开始只有1

              4、color数组初始化为0

              5、如果要更新颜色,求出变化的子树数量,更新ans

              6、至于子树数量的变化,如x的颜色变为y,那么先求出x颜色没变化时的子结点ans0,再求出颜色变化后的子结点ans1,然后ans=ans+ans0-ans1,更新ans

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
#include<algorithm>
#include<queue>
using namespace std;
#define N 100006
int n;
vector<int> edge[N];//保存边
int fa[N];//记录父节点
map<int,int>mp[N];//mp[i][j]=k表示第i个结点的颜色是j,并且和它同颜色的儿子结点数为k
int color[N];//color用来记录结点的颜色,初始化为0
void bfs()
{
queue<int> q;
q.push();
fa[]=;
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=;i<edge[u].size();i++)
{
int v=edge[u][i];
if(fa[v]!=-) continue;
fa[v]=u;
q.push(v);
}
}
}
int main()
{
int t;
scanf("%d",&t);
int ac=;
while(t--)
{
printf("Case #%d:\n",++ac);
for(int i=;i<N;i++)edge[i].clear();
memset(fa,-,sizeof(fa)); scanf("%d",&n);
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
edge[u].push_back(v);
edge[v].push_back(u);
} bfs();//bfs用来求所有的点的父节点,待会要用到 for(int i=;i<=n;i++)
{
mp[i].clear();
color[i]=;
if(i==) mp[i][]=edge[i].size();
else mp[i][]=edge[i].size()-;//这边减掉1的原因是i肯定要和1这个根结点相连,所以减1
}
//for(int i=1;i<=n;i++)
//printf("--%d\n",mp[i][0]); int q;
scanf("%d",&q);
int ans=;
while(q--)
{
int c;
scanf("%d",&c);
if(c==) printf("%d\n",ans);//如果是1就输出结果,开始只有一棵
else
{
int x,y;
scanf("%d%d",&x,&y);
int ans0=mp[x][color[x]];//ans0表示还未变色时x的子结点总数
if(x!= && color[fa[x]]==color[x]) ans0++;//如果不是根结点,并且x的父结点和它颜色相同,则++ int ans1=mp[x][y];//ans1表示x变完颜色后的子结点个数
if(x!= && color[fa[x]]==y) ans1++;//如果不是根结点,并且x的父结点和它颜色相同,则++ ans=ans+ans0-ans1;//ans加上增加的子树 if(x!=)
{
mp[fa[x]][color[x]]--;//因为要变色,所以父结点的子结点 -1
color[x]=y;//将颜色改变
mp[fa[x]][color[x]]++;//当前颜色的子结点 +1
}
color[x]=y;//如果是根节点的话,
}
}
}
return ;
}

编程之美2015初赛第一场 hihoCoder #1156 : 彩色的树(染色问题)的更多相关文章

  1. hihocoder 微软编程之美2015 初赛 第一场 (树算法 + 暴力思想 + 搜索思想)

    题目1 : 彩色的树 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定一棵n个节点的树,节点编号为1, 2, …, n.树中有n - 1条边,任意两个节点间恰好有一条路 ...

  2. hihocoder 微软编程之美2015 初赛 第二场(暴力+字典序+图论+思维算法)

    题目1 : 扑克牌 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 一副不含王的扑克牌由52张牌组成,由红桃.黑桃.梅花.方块4组牌组成,每组13张不同的面值.现在给定52 ...

  3. hihocoder #1170 机器人 &amp;&amp; 编程之美2015复赛

    题意: 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描写叙述 小冰的N个机器人兄弟排成一列,每一个机器人有一个颜色. 如今小冰想让同一颜色的机器人聚在一起.即随意两个同颜色的 ...

  4. 编程之美2015 资格赛 hihocoder 题目2: 回文字符序列

    思路:暴力搜,用BFS的方式,生成每一种可能,再对每一种可能进行判断是否回文,进行统计.严重超时!计算一个25个字符的,大概要20多秒! #include <iostream> #incl ...

  5. 编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]

    传送门 题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串ab ...

  6. 编程之美2013 初赛一 A - 竞价 学习大牛的思路

    这题我做了N久也做不出....赛后看了大牛AC的思路.... Program: #include<iostream> #include<cmath> #include<s ...

  7. 2017“编程之美”终章:AI之战勇者为王

    编者按:8月15日,第六届微软“编程之美”挑战赛在选手的火热比拼中圆满落下帷幕.“编程之美”挑战赛是由微软主办,面向高校学生开展的大型编程比赛.自2012年起,微软每年都在革新比赛命题.紧跟时代潮流, ...

  8. 编程之美2014挑战赛 复赛 Codehunt平台试题答案

    var appInsights=window.appInsights||function(config){ function r(config){t[config]=function(){var i= ...

  9. LeetCode:Climbing Stairs(编程之美2.9-斐波那契数列)

    题目链接 You are climbing a stair case. It takes n steps to reach to the top. Each time you can either c ...

随机推荐

  1. Android Clipboard(复制/剪贴板)

    Android提供的剪贴板框架,复制和粘贴不同类型的数据.数据可以是文本,图像,二进制流数据或其它复杂的数据类型. Android提供ClipboardManager.ClipData.Item和Cl ...

  2. structured sparsity model

    Data representation往往基于如下最小化问题:         (1) 其中X是观测到的数据的特征矩阵,D是字典,Z是字典上的描述.约束项和使得字典dictionary和描述code具 ...

  3. IRQL_NOT_LESS_OR_EQUAL的问题最终算攻克了

    今日想提高我那台古董笔记本extensa 4620Z的执行效率.方便我编程. 我先用万能的硬件检測工具,反正也就那几个流氓软件看了下.内存是ddr2的.我也顺带补习了一下许久不碰的硬件知识.ddr2和 ...

  4. 苹果的HomeKit协议

    苹果的HomeKit协议非常底层,其作用仅限于让iOS平台和家居设备能够相互“握手”,但“认识”之后,想要继续控制灯.空调等设备,仍然需要家电厂商在HomeKit的基础上进行二次开发.

  5. NumberBox( 数值输入框) 组件

    本节课重点了解 EasyUI 中 NumberBox(数值输入框)组件的使用方法,这个组件依赖于 ValidateBox(验证框)组件.一. 加载方式//class 加载方式<input typ ...

  6. Linux命令之用户与组管理

    介绍 Linux操作系统中,任何文件都归属某一特定的用户,而任何用户都隶属至少一个用户组.用户是否有权限对某文件进行访问.读写以及执行,受到系统严格约束的正式这种清晰.严谨的用户与用户组管理系统.在很 ...

  7. Flexbox属性查询列表

    1.任何一个flexbox布局的第一步是需要创建一个flex容器.为此给元素设置display属性的值为flex.在Safari浏览器中,你依然需要添加前缀-webkit. .flexcontaine ...

  8. [JavaScript] 判断键盘同时按某些键时执行操作。

    前言:之前知乎上看到过一个介绍国外炫酷网站的,其中一个敏感网站用同时按住"q.a.p.l" 才能观看视频 放手则立即强制停止 (手动斜眼).这个功能的实际用处,我认为是可以在做一些 ...

  9. C#SaveFileDialog的使用

    SaveFileDialog sfd = new SaveFileDialog(); //默认打开的路径 sfd.InitialDirectory = "C:\\Users\\Adminis ...

  10. jdbc 获取connection 对象的三种方式

    获取数据库连接方法一:驱动实现类 //创建mysql的Driver对象 Driver driver=new com.mysql.jdbc.Driver(); //jdbc url 定位一个数据库: S ...