题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6035

题目大意:给你一棵树,树上每个节点都有一个颜色。 现在定义两点间的距离为两点最短路径上颜色集合大小,求该树上所有点对的距离之和。其中树上的节点个数$≤2*10^5$

如果直接处理每一条路径上颜色集合大小,显然比较麻烦。我们不妨换一种思路。

我们用S_i表示经过颜色i的路径的数量,显然答案$=\sum S_i$。

考虑如何求S_i。我们先将所有颜色为i的节点全部找出来,按照dfs序排序。

显然,若树上所有的路径均经过该颜色的节点,则$S_i=\frac{n*(n-1)}{2}$。

对于该点集中的节点x的每一棵子树,不妨设当前子树的根节点为v,找出所有点集中满足$dfn[v]<dfn[u]≤low[v]$且不存在$y$,使得$dfn[v]<dfn[y]<dfn[u]≤low[v]$的所有的$u$,则显然有$\frac{(siz[v]-\sum siz[u]) \times (siz[v]-\sum siz[u]-1)}{2}$个点对不会对答案产生贡献。其中$siz[x]$表示以x为根的子树的节点个数。

该统计方法的时间复杂度为$O(n log n)$

 #include<bits/stdc++.h>
#define L long long
#define M 200005
using namespace std;
struct edge{int u,next;}e[M*]={}; int head[M]={},use=;
void add(int x,int y){use++;e[use].u=y;e[use].next=head[x];head[x]=use;} int dfn[M]={},low[M]={},t=;
int siz[M]={},col[M]={}; void dfss(int x,int fa){
dfn[x]=++t; siz[x]=;
for(int i=head[x];i;i=e[i].next) if(e[i].u!=fa){
dfss(e[i].u,x);
siz[x]+=siz[e[i].u];
}
low[x]=t;
}
bool cmp(int x,int y){
if(col[x]==col[y]) return dfn[x]<dfn[y];
return col[x]<col[y];
}
int p[M]={};
L ans=,sum=,n; void dfs(int &x,int y){
int xx=p[x]; x++;
for(int i=head[xx];i;i=e[i].next)
if(dfn[xx]<dfn[e[i].u]){
int v=e[i].u;
L cnt=siz[v];
while(x<=y&&dfn[p[x]]<=low[v]){
cnt-=siz[p[x]];
dfs(x,y);
}
sum-=cnt*(cnt-);
}
}
int hh=;
int Main(){
hh++;
ans=; sum=; t=;
memset(head,,sizeof(head)); use=;
for(int i=;i<=n;i++) scanf("%d",col+i);
for(int i=;i<n;i++){
int x,y; scanf("%d%d",&x,&y);
add(x,y); add(y,x);
}
dfss(,); add(,);
for(int i=;i<=n;i++) p[i]=i;
sort(p+,p+n+,cmp);
for(int i=,j;i<=n;i=j+){
for(j=i;col[p[i]]==col[p[j]];j++); j--;
sum=n*(n-);
p[--i]=;
dfs(i,j);
ans+=sum;
}
printf("Case #%d: %lld\n",hh,ans/);
//cout<<ans/2<<endl;
} int main(){
freopen("in.txt","r",stdin);
while(cin>>n) Main();
}

【hdu6035】 Colorful Tree dfs序的更多相关文章

  1. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  2. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  3. poj 3321 Apple Tree dfs序+线段树

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K       Description There is an apple tree outsid ...

  4. [poj3321]Apple Tree(dfs序+树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26762   Accepted: 7947 Descr ...

  5. Codeforces Round #225 (Div. 1) C. Propagating tree dfs序+树状数组

    C. Propagating tree Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/383/p ...

  6. Codeforces Round #200 (Div. 1)D. Water Tree dfs序

    D. Water Tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/343/problem/ ...

  7. POJ3321Apple Tree Dfs序 树状数组

    出自——博客园-zhouzhendong ~去博客园看该题解~ 题目 POJ3321 Apple Tree 题意概括 有一颗01树,以结点1为树根,一开始所有的结点权值都是1,有两种操作: 1.改变其 ...

  8. [Split The Tree][dfs序+树状数组求区间数的种数]

    Split The Tree 时间限制: 1 Sec  内存限制: 128 MB提交: 46  解决: 11[提交] [状态] [讨论版] [命题人:admin] 题目描述 You are given ...

  9. Codeforces Round #381 (Div. 2) D. Alyona and a tree dfs序+树状数组

    D. Alyona and a tree time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. SpringBoot集成篇(二) 异步调用Async

    什么是异步调用? 异步调用是相对于同步调用而言的,同步调用是指程序按预定顺序一步步执行,每一步必须等到上一步执行完后才能执行,异步调用则无需等待上一步程序执行完即可执行. 如何实现异步调用? 多线程, ...

  2. 使用WebUploader客户端批量上传图片,后台使用springMVC接收实例

    使用WebUploader客户端批量上传图片,后台使用springMVC接收实例 我是搞Java后台的,因为最近主管让用webUploader写客户端,但是在网上找了很多,能够复制就能用的并没有几个, ...

  3. 2018.10.14 loj#6012. 「网络流 24 题」分配问题(费用流)

    传送门 费用流水题. 依然是照着题意模拟建边就行了. 为了练板子又重新写了一遍费用流. 代码: #include<bits/stdc++.h> #define N 305 #define ...

  4. springcloud-eureka简单实现

    请参考 spring+cloud为服务实战 第三章 一.创建Eureka服务 1.使用Idea创建一个项目 结构如下: 2.pom.xml配置: <?xml version="1.0& ...

  5. Django基础(二)

    https://www.cnblogs.com/yuanchenqi/articles/5716193.html

  6. opp小节

    本章总结 练习题 面向对象三大特性,各有什么用处,说说你的理解. 类的属性和对象的属性有什么区别? 面向过程编程与面向对象编程的区别与应用场景? 类和对象在内存中是如何保存的. 什么是绑定到对象的方法 ...

  7. vivado用法

    声明为”DEBUG”,即使没有连接到其他模块,也不会被优化掉.但并不是所有的信号都是在声明为“debug”属性之后就不会优化掉. (2)同一个bank中能设置一个电平. (3)

  8. 信息管理代码分析<二>读取二进制文件数据

    first和end做为全局变量,分别指向链表的头和尾.建立链表的方式也比较简易,从二进制文件数据块中,依次从头到尾读取,每读取一个就建立一个结点. /*基本模型*/ EMP *emp1; while( ...

  9. golang的json操作[转]

    package main   import (     "encoding/json"     "fmt"     "os" )   typ ...

  10. 关于RabbitMQ一点

    RabbitMQ是AMQP(高级消息队列协议)的标准实现,理论上可以保证消息发送的准确性 RabbitMQ是用Erlang语言编写的,而Erlang语言具有以下特点: 并发性--Erlang支持超大量 ...