HDU6035 Colorful Tree
题目链接:https://vjudge.net/problem/HDU-6035
题目大意:
多样例输入。
对于每一个样例,给出 n \((2 \le n \le 200000)\) 个结点的一棵树,各个节点都有各自的颜色 \(c_i (1 \le c_i \le n)\),树上任意两点之间的路径的权值为该路径经过的不同颜色的结点数,求树上所有两点路径的权值之和。
知识点: 树、DFS
解题思路:
求树上所有的两点路径的权值之和,可以转化为求各个颜色在各条路径中的贡献值(即该颜色能够为树上的各条路径增加的权值的总和,也可以理解成是该颜色在多少条路径中出现)。但是,并没有非常好的方法可以直接求出这个总的贡献值,于是,我们可以反过来求:各个颜色在多少条路径中没有出现。
如图1所示,树上所有的红色结点将整棵树分成了 5 个联通块(笔者已用 1~5 标出),则这五个联通块里面的所有路径显然都没有经过红色结点。其实这些联通块也可以看成是一棵子树,对于一棵有 n 个结点的树,树上所有路径数为 \(\frac{n(n-1)}{2}\) 1
那么,我们所要求的答案其实就是\(\frac{NumberOfColors \times n \times (n-1)}{2}\) - 没有经过各个颜色的所有路径数
对于每一种颜色,没有经过该种颜色的路径可以分成两类:
1、从树根以下,到第一次接触颜色点之前的这一联通块的路径(如图1中的第1块);
2、颜色点之间和颜色点以下直到叶子的联通块(如图1中的第2~5块)。
只要算出这两种路径的总数,即可求出答案,但此题的实现并不简单,请看代码及注释:
AC代码:
#include <cstdio>
#include <vector>
#include <set> using namespace std;
typedef long long ll;
const int maxn=+; int color[maxn];//记录各个结点的颜色
ll sum[maxn];//精髓所在
ll sizes[maxn];//记录各个结点以下的结点数
vector<int> tree[maxn];//记录树
set<int> col;
ll ans;
void find_size(int fa,int gfa){//找出各点的 sizes[i]
sizes[fa]=;
for(int i=;i<tree[fa].size();i++){
if(tree[fa][i]==gfa) continue;
find_size(tree[fa][i],fa);
sizes[fa]+=sizes[tree[fa][i]];
}
}
void find_ans(int fa,int gfa){
ll tmp=;
if(sum[color[fa]]!=){
//此处 sum[color[fa]] 记录的是目前已知的从各个分枝的第一个颜色为 color[fa] 的点到叶子的结点数,那么当最后求出这个值以后,上文提及的第一类路径的结点数即为 n-sum[i]
tmp=sum[color[fa]];
sum[color[fa]]=;
/* ***************** */
}
for(int i=;i<tree[fa].size();i++){
if(tree[fa][i]==gfa) continue;
find_ans(tree[fa][i],fa);
//此处sum[color[fa]]用于求从 tree[fa][i] 这个结点出发到下一个颜色为 color[fa] 或者叶子的联通块的结点数
//请注意上下两处划线处的代码
ans-=(sizes[tree[fa][i]]-sum[color[fa]])*(sizes[tree[fa][i]]-sum[color[fa]]-)/;
sum[color[fa]]=;
/* ***************** */
}sum[color[fa]]=sizes[fa]+tmp;
}
int main(){
int n,a,b;
int kase=;
while(scanf("%d",&n)==){
col.clear();
for(int i=;i<=n;i++){
sum[i]=;
tree[i].clear();
}
for(int i=;i<=n;i++){
scanf("%d",&color[i]);
col.insert(color[i]);
}
ans=(ll)col.size()*n*(n-)/;
for(int i=;i<n;i++){
scanf("%d%d",&a,&b);
tree[a].push_back(b);
tree[b].push_back(a);
}find_size(,);
find_ans(,);
set<int>::iterator pt=col.begin();
for(;pt!=col.end();pt++){
int cl=*pt;
ans-=(n-sum[cl])*(n-sum[cl]-)/;
}
printf("Case #%d: %lld\n",kase++,ans);
}return ;
}
1、n(n-1)/2——此处的公式可能会挂,原因不明......
HDU6035 Colorful Tree的更多相关文章
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
/** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...
- hdu-6035 Colorful Tree
题目意思是计算所有路径(n*(n-1)/2)经过的不同颜色的数目和. 这个数目和可以转化为每种颜色经过的路径数目的求和,而这个求和又等价于颜色总数*n*(n-1)/2-没有经过某种颜色的边的数量的求和 ...
- 【树形dp】hdu6035 Colorful Tree
非常棒的题解,我就不复述了:http://blog.csdn.net/Bahuia/article/details/76141574 O(n) #include<cstdio> #incl ...
- HDU-6035 Colorful Tree(树形DP) 2017多校第一场
题意:给出一棵树,树上的每个节点都有一个颜色,定义一种值为两点之间路径中不同颜色的个数,然后一棵树有n*(n-1)/2条 路径,求所有的路径的值加起来是多少. 思路:比赛的时候感觉是树形DP,但是脑袋 ...
- HDU6035:Colorful Tree(树形DP)
传送门 题意 给出一棵最小生成树及每个节点的颜色,询问\(\frac{n(n-1)}2\)条路径的权值和,一条路径的权值为该路径的颜色种数 分析 勉强理解了ftae的做法,但是代码还是不太会,还是太弱 ...
- 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】
Colorful Tree Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)T ...
- AtCoder Beginner Contest 133 F Colorful Tree
Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...
- HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1
/* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...
- [HDU6793] Tokitsukaze and Colorful Tree
题目 又是一个条历新年,窗前的灼之花又盛开了. 时隔多年,现在只有这一棵树上盛开着残存的 \(n\) 朵灼之花了. 尽管如此,这些灼之 花仍散发出不同色彩的微弱的光芒. 灼之花的生命极为短暂,但它的花 ...
随机推荐
- Google Play商店为预注册的游戏和应用提供自动安装功能
谷歌 Play 商店一直在准备一项功能,它可以自动安装用户预先注册的应用程序和游戏.似乎该功能现已开始向第一批用户推出.有些人在预注册时会看到一个新选项,使他们能够利用发布时自动安装的功能. 用户在 ...
- Python3 字符串格式化(%操作符)
格式符 格式符为真实值预留位置,并控制显示的格式.格式符可以包含有一个类型码,用以控制显示的类型,如下: %s 字符串 (采用str()的显示) %r 字符串 (采用repr()的显示) ...
- 企业云桌面-03-安装第1个企业 CA-013-CA01
作者:学 无 止 境 QQ交流群:454544014 注意: <企业云桌面>系列博文是<企业云桌面规划.部署与运维实践指南>的基础部分,因为书中内容涉及非常多,非常全面,所以基 ...
- Yii项目Security加密解密类提取
<?php /** * @link http://www.yiiframework.com/ * @copyright Copyright (c) 2008 Yii Software LLC * ...
- Nodejs与Mysql交互实现(异步写法,同步写法)
https://blog.csdn.net/think_A_lot/article/details/93498737
- 网络流--最大流--POJ 1273 Drainage Ditches
链接 Description Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clov ...
- CUDA编程学习相关
1. CUDA编程之快速入门:https://www.cnblogs.com/skyfsm/p/9673960.html 2. CUDA编程入门极简教程:https://blog.csdn.net/x ...
- centos7 源码安装goaccess
1. 使用yum安装在不同服务器上可能失败, 推荐使用源码安装goaccess # 安装依赖 yum install -y ncurses-devel GeoIP-devel.x86_64 tokyo ...
- BAN-Bank Notes(更麻烦的背包方案)
传送门 这题的记录方案,真是,毒瘤........ \(很明显的二进制优化多重背包\) \(重点是,如何记录方案?\) \(用一维的pre数组是不行的!!(不信你去试试,方案之间选的物品会重复)\) ...
- JavaScript 浅析数组对象与类数组对象
数组(Array对象) 数组的操作 创建数组方法 添加与修改数组元素 删除数组元素 使用数组元素 遍历数组元素 多维数组 数组相关的函数 concat() join() pop() push() sh ...