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: 这样单单的求, ...
随机推荐
- UVa 557 Burger (概率+递推)
题意:有 n 个牛肉堡和 n 个鸡肉堡给 2n 个客人吃,在吃之前抛硬币来决定吃什么,如果剩下的汉堡一样,就不用投了,求最后两个人吃到相同的概率. 析:由于正面考虑还要要不要投硬币,太麻烦,所以我们先 ...
- yzm10铺瓷砖 yzm10原创系列
yzm10铺瓷砖 一天yzm10接到任务,要求用2×1大小的瓷砖,来铺2×4的地面,地面需要恰好被铺满.这对yzm10来说太容易了,于是他马上设计出了5种不同的铺法(旋转情况算不同种,如图示2.4). ...
- 点击a标签 跳到当前页面指定div
给标签div设一个id值 <div id="aa"><div> a标签抓取id值,点击跳过去 <a href="#aa">& ...
- VC++11 编译中的一些问题的解决办法
1. vc++ 的编译器的错误往往定位在错误的那一处,但是那一处可能在库的底层,而我们知道库,一般都不会错. 这时候应该好好看看我们自己的头文件是否正确,有可能头文件中的一些错误引发了连锁反应. 2 ...
- Codevs 1247 排排站
1247 排排站 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description FJ的N头奶牛有一些共同 ...
- DOM0、DOM2级事件
JavaScript DOM0.DOM2级事件 1.DOM0级事件:on+事件类型 在html行内直接绑定,也就是通过行内js绑定的例如<span onclick="alert('1' ...
- 阿里巴巴开源性能监控神器Arthas初体验
如果问性能测试中最难的是哪部分,相信很多人会说“性能调优”.确实是这样,性能调优是一个非常复杂.技术含量很高的工作.涉及到的知识面很广.以我多年从业经验来看,在企业里,大多数的性能调优都是由开发架构师 ...
- 部署spark 1.3.1 standalong模式
之前已经写过很多次部署spark 的博客,但是之前部署都是照瓢画葫芦,不得其中的细节,并且以前都是部署spark on yarn 部署环境 scala 2.10.2,jdk 1.6,spark 版本1 ...
- C#求圆的周长、面积、体积
窗体应用程序 private void button1_Click(object sender, EventArgs e) { double r; r = Convert.ToInt32(textBo ...
- mySql分组排序
mysql 排序学习---mysql 1.建表语句 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varc ...