题意略。

思路:有n * (n - 1) / 2这么多边,要枚举是不可能的,感觉和数据结构也沾不上边。再加上树上染色,以一条边上不同颜色作为这个边的值,这看起来像是算贡献那种题,和17icpc沈阳的某题有点像。

那么,我们要枚举每个边不行,不如就假设所有边上都有全部颜色,然后再减去sum(wi)[wi是第i种颜色在多少边上没出现]。

为了计算wi,我们需要知道,如果在树上的一个联通块内,不包含颜色i,那么这个联通块(假设它的点数是k)内的这k * (k - 1) / 2条边都会对wi产生贡献。

那么我们的目标就是找出所有对wi产生贡献的联通块,此时我们可以利用树的性质:siz(某个联通块) =  siz(根) -  siz(子树);

当然,我们算贡献要以子树为单位计算贡献。

定义:sum[color[cur]] = 搜索到当前节点,颜色为color[cur]的各个最高子树的节点之和。

详见代码:

#include<bits/stdc++.h>
#define maxn 200050
using namespace std;
typedef long long LL; LL siz[maxn],color[maxn],sum[maxn],visit[maxn],colors;
LL contri;
vector<int> graph[maxn]; LL dfs(int cur,int fa){
siz[cur] = ;
LL allgap = ;
for(int i = ;i < graph[cur].size();++i){
int chi = graph[cur][i];
if(chi == fa) continue;
LL keep = sum[color[cur]];
siz[cur] += dfs(chi,cur);
LL gap = siz[chi] - (sum[color[cur]] - keep);
contri += gap * (gap - ) / ;
allgap += gap;
}
sum[color[cur]] += (allgap + );
return siz[cur];
}
void init(){
for(int i = ;i < maxn;++i) graph[i].clear();
memset(visit,,sizeof(visit));
memset(sum,,sizeof(sum));
colors = contri = ;
} int main(){
LL cas = ,n;
while(scanf("%lld",&n) == ){
init();
for(int i = ;i <= n;++i){
scanf("%lld",color + i);
if(visit[color[i]] == ){
visit[color[i]] = ;
++colors;
}
}
int x,y;
LL ans = (n * (n - )) / * colors;
for(int i = ;i < n - ;++i){
scanf("%d%d",&x,&y);
graph[x].push_back(y);
graph[y].push_back(x);
}
dfs(,);
for(int i = ;i <= n;++i){
if(visit[i]){
contri += (n - sum[i]) * (n - sum[i] - ) / ;
}
}
printf("Case #%lld: %lld\n",cas++,ans - contri);
}
return ;
}

其中求联通块的点数用到了取差值的方法,gap就是联通块的大小,最后的sum[color[cur]] += (allgap + 1)的意思是,这些联通块本身也是子树的一部分,在算最高子树的时候也应计入在内,那个1表示的是

根节点。

最后contri += (n - sum[i]) * (n - sum[i] - 1) / 2;这是因为我们在算联通块的时候其实都是在算子树的联通块,未能把根节点算在内,这里要补上,是因为已经到整棵树的根节点了,不会再有父节点了。

带给我的收获:

1.正面不行的时候可以考虑反面。

2.联通块与边的关系。

3.联通块size的计算。

最新文章

  1. APP测试入门篇之APP基础知识(001)
  2. Customizing the Editor
  3. js阻塞
  4. Memcached安装及配置
  5. IOS--工作总结--post上传文件(以流的方式上传)
  6. 【POJ】3009 Curling 2.0 ——DFS
  7. 怎么限制Google自己主动调整字体大小
  8. Shiro集成Web
  9. Android的Service组件
  10. Random-Forest-Python
  11. 排序之选择排序(SelectSort)
  12. Error in loadNamespace 的解决之道
  13. 初始IP协议
  14. P2080 增进感情(背包DP)
  15. .net ML机器学习中遇见错误记录
  16. solidworks建立三维模型里面的几何对象和工程图里面的元素的联系
  17. iframe可通过postMessage解决跨域、跨窗口消息传递
  18. 《Linux内核设计与实现》第一、二章学习笔记
  19. 24.python中类的方法
  20. modelsim 出现此错误怎么办

热门文章

  1. 如何判断NSDictionary是否包含某个键
  2. 阿里云Maven配置,Maven仓库配置,Maven镜像配置
  3. 【JMedia】诺贝尔奖得主:东亚教育浪费了太多生命
  4. flannel 网络问题排查
  5. python3 第四章 - 输入与输出
  6. httpd: Could not reliably determine the server&#39;s fully qualified domain name, using ::1 for ServerName
  7. [Qt Quick] No rule to make target问题解决办法
  8. sqlserver datetime的bug
  9. junit设计模式--命令者模式
  10. &lt;global-results&gt;标签来定义全局的&lt;result&gt;