【题目链接】 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. 关于cocos2d-x 中 CCEditBox 的输入位置和IOS虚拟键盘位置不重合的bug

    这个文章的名字起的实在是有点长,主要是怕说不清楚. 在IOS上,输入时,我看到过的比较少,就两种,如附件两张图.一个是虚拟键盘的输入框完全是在CCEditBox上,另一张虚拟键盘的输入区域是紧挨着键盘 ...

  2. max_element和min_element的用法

    首先,max_element和min_elemetn看字面意思是求最大值和最小值,这个确实是这个意思.不过,需要注意的是,他返回的是最大值(最小值)的地址,而非最大值(最小值).对于一般数组的用法则是 ...

  3. Winform Socket通信

    Socket相关概念[端口] 在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务.每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应 ...

  4. new操作符的内部运行解析

    在加上new操作符,我们就能完成传统面向对象的class + new的方式创建对象,在Javascript中,我们将这类方式成为Pseudoclassical. 基于上面的例子,我们执行如下代码   ...

  5. 【EverydaySport】健身笔记——动态牵拉

    动态牵拉,包含了动态和牵拉两个概念.动态牵拉要求牵拉的过程要伴随着走路,即行进中牵拉,动态牵拉不仅可以使得肌肉得到延展,还可以激活肌肉协同工作,发展协调性.灵活性.进行动态牵拉时每个动作要进行5~10 ...

  6. 自动化测试===unittest和requests接口测试案例,测试快递查询api(二)

    在原来基础上生成测试报告: 首先需要  HTMLTestRunner.py 的unittest生成报告文件 (源码,自动化测试===unittest配套的HTMLTestRunner.py生成html ...

  7. vim常用命令(复习版)(转)

    原文链接:http://blog.csdn.net/love__coder/article/details/6739670 1.光标移动 上:k 下:j 左:l 『字母L小写』 右:h 上一行行首:- ...

  8. 在 Visual Studio 中使用正则表达式

    Visual Studio 使用 .NET framework 正则表达式查找和替换文本. 在 Visual Studio 2010 和早期版本中,Visual Studio 在“查找和替换”窗口中使 ...

  9. leetcode 之Remove Nth Node From End of List(19)

    这题比较简单,方法有很多.其中一种比较有意思的做法是设置两个指针,一个先走n步,然后再一起走.一个到了末尾,另一个也就确定了要删除元素的位置. ListNode *removeNthFromEnd(L ...

  10. django “如何”系列8:如何为模型提供初始化数据

    当你第一次配置一个app的时候,有时候使用硬编码的数据去预填充你的数据库是非常有用的.这里有几个你可以让django自动创建这些数据的方法:你可以提供固定格式的初始化数据或者提供通过SQL初始化数据. ...