【题目链接】 http://acm.hdu.edu.cn/showproblem.php?pid=6035

【题目大意】

  给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值

【题解】

单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和。
  反过来思考只需要求有多少条路径没有经过这种颜色即可。
  直接做可以采用虚树的思想(不用真正建出来),对每种颜色的点按照 dfs 序列排个序,
  就能求出这些点把原来的树划分成的块的大小。
  在搜索的过程中我们保存每个颜色的父节点,一遍dfs即可得到答案。

【代码】

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
typedef long long LL;
const int N=200010;
vector<int> v[N];
LL ans;
int n,x,y,Cas=1,c[N],pre[N],lft[N],cut[N];
LL sum2(LL x){return x*(x-1)/2;}
int dfs(int x,int fx){
int res=1,fa=pre[c[x]];
pre[c[x]]=x;
for(int i=0;i<v[x].size();i++){
int y=v[x][i];
if(y==fx)continue;
cut[x]=0;
int sz=dfs(y,x);
res+=sz;
ans-=sum2(sz-cut[x]);
}(fa?cut[fa]:lft[c[x]])+=res;
pre[c[x]]=fa;
return res;
}
int main(){
while(~scanf("%d",&n)){
for(int i=1;i<=n;i++)scanf("%d",&c[i]),v[i].clear(),pre[i]=cut[i]=lft[i]=0;
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}ans=sum2(n)*n; dfs(1,1);
for(int i=1;i<=n;i++)ans-=sum2(n-lft[i]);
printf("Case #%d: %lld\n",Cas++,ans);
}return 0;
}

HDU 6035 Colorful Tree(补集思想+树形DP)的更多相关文章

  1. HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1

    /* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...

  2. 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 ...

  3. hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】

    题目链接 单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和.反过来思考只需要求有多少条路径没有经过这种颜色即可. 具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细 ...

  4. 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 ...

  5. HDU 6035 Colorful Tree (树形DP)

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=6035 [题目大意] 给出一颗树,一条路径的价值为其上点权的种类数,求路径总价值 [题解] 我们计算 ...

  6. hdu 6035 Colorful Tree(虚树)

    考虑到树上操作:首先题目要我们求每条路径上出现不同颜色的数量,并把所有加起来得到答案:我们知道俩俩点之间会形成一条路径,所以我们可以知道每个样例的总的路径的数目为:n*(n-1)/2: 这样单单的求, ...

  7. HDU 6035 Colorful Tree(dfs)

    题意:一棵有n个点的树,树上每个点都有颜色c[i],定义每条路径的值为这条路径上经过的不同颜色数量和.求所有路径的值的和. 可以把问题转化为对每种颜色有多少条不同的路径至少经过这种颜色的点,然后加和. ...

  8. [HDU 5293]Tree chain problem(树形dp+树链剖分)

    [HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...

  9. Codeforces 791D Bear and Tree Jump(树形DP)

    题目链接 Bear and Tree Jumps 考虑树形DP.$c(i, j)$表示$i$最少加上多少后能被$j$整除. 在这里我们要算出所有$c(i, k)$的和. 其中$i$代表每个点对的距离, ...

随机推荐

  1. 如何用js自己实现Animate运动函数

    js运动是我们学习js必不可少的研究部分,首先我们要知道js的运动其实仅仅是不断改变元素的某个属性值而已,比如不断改变一个绝对定位div的left值,那么你看到的效果就是这个div不断的向右边运动,那 ...

  2. 【转】MP3文件原理及结构解析

    1.引言文件压缩技术的日新月异使得MP3成为时下最烫手的音乐格式,优质的音乐随着0与1的排列迅速散布 到世界各地,撼动人心.何谓MP3?MP3的全称是MPEG Audio Layer 3,它是一种高效 ...

  3. monkey测试===如何获取android app的Activity

    方法一(推荐): 手机连接adb,手机界面在需要取得activity的界面. 推荐使用该命令: adb shell dumpsys activity top | findstr ACTIVITY 获取 ...

  4. Makefile系列之一 : 书写规则

    1. 规则 target : prerequisites command  2. example excute 为最终生成的可执行文件. 可以通过命令 make clean来删除所有编译时产生的中间文 ...

  5. UIResponder简介

    1.简介 在使用设备的时候我们大多时候是但手指触摸控件了进行的,比如点击密码按钮解锁,上下浏览网页等动作.你肯定也摇动过iphone抢红包和***等等,我们的系统可以处理这些事件则都需要去使用UIRe ...

  6. dos命令连接mysql并且查看编码方式

    打开cmd: 输入:mysql -hlocalhost -uroot -p 然后: show variables like 'char%';

  7. html5重力感应事件之DeviceMotionEvent

    前言 今天主要介绍一下html5重力感应事件之DeviceMotionEvent,之前我的一篇文章http://www.haorooms.com/post/jquery_jGestures, 介绍了第 ...

  8. JavaScript 正则表达式的入门与使用

    知道正则表达式已经很久了,粗略会看懂一些,不过以前没有系统的学习,最近在看<JS权威指南>,刚好看到了看到正则表达式部分,就比较系统的学习了正则表达式. 先说一下正则表达式的一些基本知识 ...

  9. C++智能指针: auto_ptr, shared_ptr, unique_ptr, weak_ptr

    本文参考C++智能指针简单剖析 内存泄露 我们知道一个对象(变量)的生命周期结束的时候, 会自动释放掉其占用的内存(例如局部变量在包含它的第一个括号结束的时候自动释放掉内存) int main () ...

  10. 生成RSA2公钥、私钥

    RSA2是一种被使用广泛的非对称加密算法. openssl OpenSSL> genrsa -out app_private_key.pem # 私钥RSA2 OpenSSL> rsa - ...