HDU-6035 Colorful Tree(树形DP) 2017多校第一场
题意:给出一棵树,树上的每个节点都有一个颜色,定义一种值为两点之间路径中不同颜色的个数,然后一棵树有n*(n-1)/2条
路径,求所有的路径的值加起来是多少。
思路:比赛的时候感觉是树形DP,但是脑袋抽了,忘记树形DP是怎么遍历的了(其实没忘也不会做:)
先给出官方题解吧:
单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和。反过来思考只需要求有多少条路径没有经过这种颜色即可。直接做可以采用虚树的思想(不用真正建出来),对每种颜色的点按照 dfs 序列排个序,就能求出这些点把原来的树划分成的块的大小。这个过程实际上可以直接一次 dfs 求出。
其实感觉就前面那两句能看懂= =,不过这个也才是主要的。很显然这题是算每个节点的贡献,但是每个节点都算的话就会算重,去重不容易,所以就可以计算
有哪些路径没有经过这种颜色,这个就很容易一点了,所以对于每种颜色就是求他的联通快的大小。
然后感觉还是不容易,可能是树形DP做少了吧,通过这个题还是学到不少的技巧 比如通过访问节点前,把前面的颜色给存起来,这样到时候访问的就是这颗子树的内容了,更新这些内容的时候一定要注意他们之间的关系
/** @xigua */
#include<stdio.h>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<set>
#include<string>
#include<map>
#define PI acos(-1)
using namespace std;
typedef long long ll;
typedef double db;
const int maxn = 2e5 + 5;
const ll maxm = 1e7;
const int mod = 1e9 + 7 + 0.1;
const int INF = 1e9 + 7;
const ll inf = 1e15 + 5;
const db eps = 1e-9;
const int state = 15;
ll ans, col[maxn];
int head[maxn], cnt, n, siz[maxn], vis[maxn], c[maxn];
struct Edge {
int v, next;
} e[maxn<<1]; void add(int u, int v) {
e[cnt].v = v;
e[cnt].next = head[u];
head[u] = cnt++;
} void init() {
cnt = ans = 0;
memset(head, -1, sizeof(head));
memset(vis, 0, sizeof(vis));
memset(col, 0, sizeof(col));
} void dfs(int u, int fa) {
siz[u] = 1;
vis[c[u]] = 1;
int pre = col[c[u]]; //访问节点前的
int num = 0; //因为一个节点有好几个儿子,所以就要把前面的给剔除
for (int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if (fa == v) continue;
dfs(v, u);
siz[u] += siz[v];
ll tmp = siz[v] - (col[c[u]] - pre - num);
ans -= (tmp - 1) * tmp / 2;
num = col[c[u]] - pre; //num就是当前颜色的个数减去以前的就是节点u的前面的儿子的
}
col[c[u]] = pre + siz[u];
} void solve() {
int cas = 1; while (cin >> n) {
init();
for (int i = 1; i <= n; i++)
scanf("%d", c + i);
for (int i = 1; i < n; i++) {
int u, v; scanf("%d%d", &u, &v);
add(u, v); add(v, u);
}
dfs(1, -1);
for (int i = 1; i <= n; i++) {
if (vis[i]) {
ans += (ll)n * (n - 1) / 2;
ll tmp = n - col[i];
ans -= tmp * (tmp - 1) / 2;
}
}
printf("Case #%d: %I64d\n", cas++, ans);
}
} int main() {
int t = 1, cas = 1;
//freopen("in.txt", "r", stdin);
// scanf("%d", &t);
// init();
while(t--) {
// printf("Case #%d:\n", cas++);
solve();
}
return 0;
}
HDU-6035 Colorful Tree(树形DP) 2017多校第一场的更多相关文章
- HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1
/* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...
- 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 ...
- hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】
题目链接 单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和.反过来思考只需要求有多少条路径没有经过这种颜色即可. 具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细 ...
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
/** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...
- 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 ...
- HDU 6035 Colorful Tree(补集思想+树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 单独考虑 ...
- HDU 6035 Colorful Tree (树形DP)
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 我们计算 ...
- HDU 6035 Colorful Tree(dfs)
题意:一棵有n个点的树,树上每个点都有颜色c[i],定义每条路径的值为这条路径上经过的不同颜色数量和.求所有路径的值的和. 可以把问题转化为对每种颜色有多少条不同的路径至少经过这种颜色的点,然后加和. ...
- hdu 6035 Colorful Tree(虚树)
考虑到树上操作:首先题目要我们求每条路径上出现不同颜色的数量,并把所有加起来得到答案:我们知道俩俩点之间会形成一条路径,所以我们可以知道每个样例的总的路径的数目为:n*(n-1)/2: 这样单单的求, ...
随机推荐
- JQuery点击table获取点击行的数据
$(function () {var TaskType = '';$("#data_table tr:gt(0)").click(function () { TaskType = ...
- Spring Boot 学习系列(07)—properties文件读取
此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 传统的properties读取方式 一般的,我们都可以自定义一个xxx.properties文件,然后在工程 ...
- 让App飞久一点
此文已由作者杨晓授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 本文从作者所在项目进行的耗电量测试入手,介绍了移动端App耗电量测试的一些基本概念和方法,重点介绍了iOS应用 ...
- E20181001-ts
decorate vt. 装饰; 点缀; 粉刷; 授予(某人)勋章 vi. 装饰; 布置;
- 检测到"_ITERATOR_DEBUG_LEVEL"的不匹配项
error: vtkCommon.lib(vtkSmartPointerBase.obj) : error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项:值“0”不 ...
- lightoj 1078【同余定理】
题意: 给你一个n和一个数 digit ,问你最少需要多少个 digit 使得整除于n; 思路: 同余定理(a+b)%n=(a%n+b%n)%n; (m%n+m%n*10+m%n*100+m%n*10 ...
- CTP Release() 的注意问题
测试时发现CThostFtdcMdSpi有个比较严重的问题,就是使用Release()退出清理对象时 会出现死机,并且频率很高,怎样解决? 答:请参考以下代码的释放顺序. template <c ...
- qscoj53(图的m着色问题)
题目链接:http://qscoj.cn/contest/12/problem/53/ 题意:中文题诶- 思路:n个点, 那么最多用n种颜色,所以我们可以枚举颜色种类1~n,然后再判断用 i 种颜色可 ...
- Ruby测试小代码[计算50以内的素数]
算法思想 判断某一个数,能不能被比他平方根小的素数整除. 首先看看代码 $arr = [] $arr[0] = 2 def add_prime(n) 3.step(n,2){|num| $arr &l ...
- 即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?
本文引用了“蔷薇Nina”的“Nginx 相关介绍(Nginx是什么?能干嘛?)”一文部分内容,感谢作者的无私分享. 1.引言 Nginx(及其衍生产品)是目前被大量使用的服务端反向代理和负载均衡 ...