Colorful Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1539    Accepted Submission(s): 616

Sample Input
3
1 2 1
1 2
2 3
6
1 2 1 3 2 1
1 2
1 3
2 4
2 5
3 6
Sample Output
Case #1: 6
Case #2: 29
Source

题意:

一棵n个结点的树,每个结点都有颜色,定义两点之间的路径长度为路径上出现的不同颜色数目,求树上所有路径的长度和。


思路:

“真的难”系列。

官方题解:


首先这题肯定是算贡献,也就是计算出每种颜色参与了多少条路径,但这样正面考虑并不容易,不妨从反面考虑,计算每种颜色没有参与多少路径,然后拿 (路径总数 * 颜色总数) - 没参与的贡献,就是答案了。
对于一种颜色x,怎么计算没参与的路径数目呢,很显然,对于每个不包含颜色x的连通块中任意两点路径都是x不参与的贡献,那么问题就转化为,对于任意一种颜色x,需要求出每个不包含x的连通块大小。
这里利用了树形dp,对于结点u,若u的颜色为x,那么dfs(u)的过程中,我们就想知道对于u的每个儿子v构成的子树中最高的一批颜色也为x的结点是哪些,要是知道这些结点子树的大小,只要拿子树v的大小减去这些节点子树的大小,就可以得到包括v在内的没有颜色x的连通块大小。

举个例子,如图:

对于结点1,我们想求出与1相邻的且不是黑色的结点组成的连通块大小,此时就要dfs结点1的两个儿子2和3,若我们处理出来结点2中,最高的一批黑色结点(4,8)的所构成子树的大小分别为2和1,那么我们拿2为根子树的大小5,减去2,减去1,就得到了结点2不包含黑色结点的连通块大小是5-2-1=2,也就是图中的2和5组成的连通块。同理对3,可以求得连通块大小是2({3,6})。
计算出了子树u中连通块大小对答案的贡献之后,就要将当前最高一批的黑色结点更新为u,最高黑色节点构成的子树大小sum加上子树u中没有计算的那部分大小5({1,2,3,5,6})。
具体实现,看代码,sum[x]表示的遍历到当前位置,颜色为x的高度最高一批结点为根的子树大小总和。

下面给出AC代码:

 #include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + ;
typedef long long LL; LL color[MAXN], sz[MAXN], sum[MAXN], vis[MAXN];
vector <int> tree[MAXN];
LL ans; LL dfs(int u, int pa) {
sz[u] = ;
LL allson = ;
int cnt = tree[u].size();
for (int i = ; i < cnt; i++) {
int v = tree[u][i];
if (v == pa) continue;
LL last = sum[color[u]]; // 保存递归之前的sum值
sz[u] += dfs(v, u);
LL add = sum[color[u]] - last; // add就是结点v为根的子树中颜色为color[u]且高度最高的若干子树的大小
// 对于结点v来说,sz[v]-add就是v这棵子树最上端的,且不包含颜色为color[u]的连通块大小
ans += (sz[v] - add) * (sz[v] - add - ) / ; // 对这个连通块中任意两个点的路径都不包含颜色color[u]
allson += sz[v] - add; // allson记录下儿子结点v组成的不含颜色color[u]的连通块大小总和
}
sum[color[u]] += allson + ; // sum更新,此时要加上不含color[u]连通块的大小总和以及u自己
return sz[u];
} int main() {
//freopen("in.txt", "r", stdin);
int n, cs = ;
while (scanf("%d", &n) !=EOF) {
memset(vis, , sizeof(vis));
memset(sum, , sizeof(sum));
int cnt = ;
for (int i = ; i <= n; i++) {
scanf("%I64d", &color[i]);
if (!vis[color[i]]) ++cnt;
vis[color[i]] = ;
tree[i].clear();
}
for (int i = ; i < n; i++) {
int u, v;
scanf("%d%d", &u, &v);
tree[u].push_back(v);
tree[v].push_back(u);
}
printf("Case #%d: ", ++cs);
if (cnt == ) { // 只有一种颜色的特殊情况
printf("%I64d\n", (LL)n * (n - 1LL) / 2LL);
continue;
}
ans = ;
dfs(, -);
for (int i = ; i <= n; i++) { // 注意最后要对整棵树来补充所有颜色剩下的联通块
if (!vis[i]) continue;
ans += (n - sum[i]) * (n - sum[i] - 1LL) / 2LL;
}
printf("%I64d\n", (LL)n * (n - 1LL) / 2LL * cnt - ans);
}
return ;
}

2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】的更多相关文章

  1. 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  2. 2017 Multi-University Training Contest - Team 9 1003&&HDU 6163 CSGO【计算几何】

    CSGO Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Subm ...

  3. 2017 Multi-University Training Contest - Team 9 1005&&HDU 6165 FFF at Valentine【强联通缩点+拓扑排序】

    FFF at Valentine Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  4. 2017 Multi-University Training Contest - Team 9 1004&&HDU 6164 Dying Light【数学+模拟】

    Dying Light Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Tot ...

  5. 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  6. 2017 Multi-University Training Contest - Team 9 1001&&HDU 6161 Big binary tree【树形dp+hash】

    Big binary tree Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  7. 2017 Multi-University Training Contest - Team 1 1006&&HDU 6038 Function【DFS+数论】

    Function Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  8. 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】

    Balala Power! Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  9. 2017 Multi-University Training Contest - Team 1 1011&&HDU 6043 KazaQ's Socks【规律题,数学,水】

    KazaQ's Socks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

随机推荐

  1. mac上虚拟机安装旧版本的macosx 10.8

    前言 由于测试的需要,需要10.8的macosx,但又不想降级自己mac版本,所以还是装虚拟机,Parallels Desktop试验了安装不了osx,就换VMware Fusion,发现是可以的. ...

  2. mvc中signalr实现一对一的聊天

    Asp.net MVC中实现即时通讯聊天的功能.前几天刚写了一片基础入门的教程,今天就来实现一下使用signaIr实现一对一的聊天的功能,对于这种场景也是即时通讯最基本功能.好吧废话不多说.先来看一下 ...

  3. iOS音频采集过程中的音效实现

    1.背景 在移动直播中, 声音是主播和观众互动的重要途径之一, 为了丰富直播的内容,大家都会想要在声音上做一些文章, 在采集录音的基础上玩一些花样. 比如演唱类的直播间中, 主播伴随着背景音乐演唱. ...

  4. 多线程下QAxObject指针为NULL的解决办法

    项目中需要对Excel进行操作,把数据中的数据写入到Excel文件中.在数据量大的情况下,操作Excel是一件费时的操作. 但是执行到下列代码时就会出现空指针的情况: QAxObject *excel ...

  5. 最近提交一个mysql5.7的bug,提醒自己以后注意写SQL要规范

    最近帮朋友提交一个mysql5.7的bug , oracle mysql 的大神还回复我 , 以后注意书写sql规范 , 潜台词是不是不要给他们增加工作量 https://bugs.mysql.com ...

  6. 我搞zabbix的那两天(2)

    摘要:前一篇(我搞zabbix的那两天(1))我介绍了Zabbix的安装部署以及遇到的问题,这一篇将介绍zabbix 使用及短信等告警实现!!! Zabbix主界面及汉化方法介绍 1.1 初始化主界面 ...

  7. Android基础夯实--你了解Handler有多少?

    概述 对于刚入门的同学来说,往往都会对Handler比较迷茫,到底Handler是个什么样的东西.当然,可能对于一些有工作经验的工程师来说,他们也不一定能很准确地描述,我们来看下API的介绍. Han ...

  8. Android 7.1 ActivityManagerService 屏幕旋转流程分析 (四)

    四.Activity的更新(旋转) sendNewConfiguration()会调用到ActivityManagerService的updateConfiguration()来update Conf ...

  9. MySQL数据库学习: 01 —— 数据库的概述

    壹 概述 一 了解SQL 1.1 数据库基础 1.1.1 什么是数据库 数据库(database)保存有组织的数据的容器(通常是一个文件或一组文件). 易混淆:人们常常用“数据库”这个词语来代表他们使 ...

  10. jQuery基础 (四)——使用jquery-cookie 实现点赞功能

    jquery-cookie 下载地址:https://github.com/carhartl/jquery-cookie 直接上代码 html <span class="jieda-z ...