题目链接

单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和。反过来思考只需要求有多少条路径没有经过这种颜色即可。

具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细注释的代码及对应的一组自造的数据以及图片来进行解释

欢迎交流,给出意见~~~

数据

/*
第二行的1 2 3在图中分别用红黄蓝来表示
15
1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
5 10
5 11
6 12
6 13
7 14
7 15
*/

含注释的代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int N=2e5+;
int n;
int c[N]; //各结点的颜色
int size[N]; //size[i]记录结点i的子树的大小,叶子为1
int vis[N]; //vis[i]记录颜色i是否出现过
int sum[N]; //见函数内注释及图片
vector<int> adj[N];
LL ans,de; LL C(LL a,LL b) //计算组合数,这样写是为了增加后面的代码的可读性
{
LL ret=;
for(int i=;i<=b;i++)
ret=ret*(a+-i)/i;
return ret;
} void dfs(int u,int pre)
{
// 定义 u 为“当前结点”
// sum[c[u]]表示, 整棵树中,已经被dfs过的,
// 与当前结点具有相同颜色的结点的所有子树的大小之和
// 不重复计数
// 图一展示了的是刚刚进入dfs(7,3)时sum[c[u]]包含的结点
printf("\n\n==================================\nEnter->%d\n\n",u);
int all=;
size[u]=;
for(int to:adj[u])
{
if(to==pre) continue;
int sumu_bd=sum[c[u]]; //bd : before dfs
//记录此次dfs前的sum[c[u]]
dfs(to,u);
size[u]+=size[to];
int part=sum[c[u]]-sumu_bd; //dfs过后,sum[c[u]]会产生一个增量,用part来记录这个增量
all+=part; //all用来记录,对u dfs的过程中,sum[c[u]]产生的总增量
//这是在为 u返回pre时更新sum[c[u]]做准备
printf("from %d return to %d\n",to,u);
printf("all=%d,sumu_bd=%d,part=%d,sum[c[u]]=%d\n",all,sumu_bd,part,sum[c[u]]);
printf("to=%d,size[to]=%d\n",to,size[to]);
de+=C(size[to]-part,); //size[to]-part的含义: 在to为根节点的子树中,有一部分结点与to位于同一“块”,
// 这个块以 与u颜色相同的结点(不含),或是叶子(含,若叶子与u颜色相同则不含) 为边界
// size[to]-part表示的是这个块的大小
// 图二展示了 dfs(1,0)内,刚刚执行完dfs(2,1)后,更新de时的size[2]-part
printf("\nnow,de=%d\n\n",de);
}
printf("\n\n=== leaving... ===\n\n");
printf("pre_sum[c[u]]=%d\n",sum[c[u]]);
sum[c[u]]+=size[u]-all;
printf("after_sum[c[u]]=%d\n",sum[c[u]]);
printf("\nleave from %d\n\n==================================\n\n",u);
} int main()
{
int kase=;
while(~scanf("%d",&n))
{
memset(vis,,sizeof(vis));
memset(size,,sizeof(size));
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++) adj[i].clear();
int c_num=;
de=;
for(int i=;i<=n;i++)
{
scanf("%d",&c[i]);
if(!vis[c[i]]) c_num++;
vis[c[i]]=;
}
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(,);
for(int i=;i<=n;i++)
if(i!=c[]&&vis[i]) de+=C(n-sum[i],);
ans=C(n,)*c_num-de;
printf("Case #%d: %lld\n",++kase,ans);
}
}

图一:

图二:

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef long long LL; const int N=2e5+;
int n;
int c[N];
int size[N];
int vis[N];
int sum[N];
vector<int> adj[N];
LL ans,de; LL C(LL a,LL b)
{
LL ret=;
for(int i=;i<=b;i++)
ret=ret*(a+-i)/i;
return ret;
} void dfs(int u,int pre)
{
int all=;
size[u]=;
for(int to:adj[u])
{
if(to==pre) continue;
int sumu_bd=sum[c[u]];
dfs(to,u);
size[u]+=size[to];
int part=sum[c[u]]-sumu_bd;
all+=part;
de+=C(size[to]-part,);
}
sum[c[u]]+=size[u]-all;
} int main()
{
int kase=;
while(~scanf("%d",&n))
{
memset(vis,,sizeof(vis));
memset(size,,sizeof(size));
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++) adj[i].clear();
int c_num=;
de=;
for(int i=;i<=n;i++)
{
scanf("%d",&c[i]);
if(!vis[c[i]]) c_num++;
vis[c[i]]=;
}
for(int i=;i<n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(,);
for(int i=;i<=n;i++)
if(i!=c[]&&vis[i]) de+=C(n-sum[i],);
ans=C(n,)*c_num-de;
printf("Case #%d: %lld\n",++kase,ans);
}
}

简版的

hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】的更多相关文章

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

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

  2. hdu 6044 : Limited Permutation (2017 多校第一场 1012) 【输入挂 组合数学】

    题目链接 参考博客: http://blog.csdn.net/jinglinxiao/article/details/76165353 http://blog.csdn.net/qq_3175920 ...

  3. hdu 6047: Maximum Sequence (2017 多校第二场 1003)【贪心】

    题目链接 可以贪心写,先把b数组按从小到大的顺序排个序,根据b[i]的值来产生a[n+i] 借助一个c数组,c[i]记录,j从i到n,a[j]-j的最大值,再加上一个实时更新的变量ma,记录从n+1到 ...

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

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

  6. HDU-6035 Colorful Tree(树形DP) 2017多校第一场

    题意:给出一棵树,树上的每个节点都有一个颜色,定义一种值为两点之间路径中不同颜色的个数,然后一棵树有n*(n-1)/2条 路径,求所有的路径的值加起来是多少. 思路:比赛的时候感觉是树形DP,但是脑袋 ...

  7. HDU 6035 Colorful Tree(补集思想+树形DP)

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

  8. HDU 6035 Colorful Tree (树形DP)

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

  9. HDU 6035 Colorful Tree(dfs)

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

随机推荐

  1. ubuntu安装和使用git

    1.apt-get安装 apt-get install git 2.全局配置 git config --global user.name "yourname" git config ...

  2. 阅读笔记12-Java 面试题 —— 老田的蚂蚁金服面试经历

    电话一面 1.自我介绍.自己做的项目和技术领域 2.项目中的监控:那个监控指标常见的哪些? 3.微服务涉及到的技术以及需要注意的问题有哪些? 4.注册中心你了解了哪些? 5.consul 的可靠性你了 ...

  3. Tesseract5.0训练字库,提高OCR特殊场景识别率,合并字库(二)

    一.准备工作 需要的文件 tif文件和box文件. 如果你打标打好了,但是是分批次打标的,那么可以合并字库,我们最初只需要 tif 和 box 文件,如下: 二.生成对应的 .tr 训练文件 根据不同 ...

  4. Linked List Cycle(链表成环)

    判断链表中是否有环 来源:https://leetcode.com/problems/linked-list-cycle Given a linked list, determine if it ha ...

  5. “希希敬敬对”团队--‘百度贴吧小爬虫’Alpha版本展示博客

    希希敬敬对的 Alpha阶段测试报告 随笔链接地址 https://www.cnblogs.com/xiaoyoushang/p/10078826.html   Alpha版本发布说明 随笔链接地址 ...

  6. 2019寒假作业一:PTA7-1 打印沙漏

    - 打印沙漏 ( 分) 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数个符号: ...

  7. lesson2-完全图、补图和顶点度

    (一).完全图.偶图与补图 1.每两个不同的顶点之间都有一条边相连的简单图称为完全图 (complete graph).在同构意义下,n个顶点的完全图只有一个,记为 2.所谓具有二分类(X, Y)的偶 ...

  8. centos7下搭建Testlink环境详细过程

    花了半天的时间终于搭建好了完整的Testlink环境,主要包括Mysql以及PHP的版本.未关闭防火墙.以及安装配置过程中遇到的一些问题.以下是详细的搭建过程. 一.工具准备 以下是我在搭建过程中用到 ...

  9. Codeforces 840C 题解(DP+组合数学)

    题面 传送门:http://codeforces.com/problemset/problem/840/C C. On the Bench time limit per test2 seconds m ...

  10. Python笔记(读取txt文件中的数据)

    在机器学习中,常常需要读取txt文本中的数据,这里主要整理了两种读取数据的方式 数据内容 共有四列数据,前三列为特征值,最后一列为数据标签 40920 8.326976 0.953952 3 1448 ...