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 by an integer, where the color of node i is ci.
The path between each two different nodes is unique, of which we define the value as the number of different colors appearing in it.
Calculate the sum of values of all paths on the tree that has n(n−1)2 paths in total.
Input
The input contains multiple test cases.
For each test case, the first line contains one positive integers n, indicating the number of node. (2≤n≤200000)
Next line contains n integers where the i-th integer represents ci, the color of node i. (1≤ci≤n)
Each of the next n−1 lines contains two positive integers x,y (1≤x,y≤n,x≠y), meaning an edge between node x and node y.
It is guaranteed that these edges form a tree.
Output
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
Sample Input
3
1 2 1
1 2
2 3
6
1 2 1 3 2 1
1 2
1 3
2 4
2 5
3 6
Sample Output
Case #1: 6
Case #2: 29
分析:
给你一棵树 n个点,n个点有自己的颜色,每两个点的权值就是这条路上不同的颜色的种类数,问整棵树的权值。。。首先可以想到的。。一棵树上所有的边是 n×(n-1)/2 假如每个颜色都在所有的边上,那么总权值就是 总颜色 num×n×(n-1)/2 那么很简单的一个想法 是
总权值 减去多加上的权值,那么多加上的权值就是每个点的颜色不在的边的数量的总和,由于时间要求,你可能需要在on 内得到这些东西,所以你可以用类似树形dp维护,那么如何得到这个值呢。画个树的图,可以想到,每个树节点下面支路都是相连的,每一部分的求和都可以用 n×(n-1)/2。然后再运用虚树的思想,每个点管理下面它需要管理的部分。。(即只有它自身的这种颜色,别的颜色看作无色,那么每个节点的管理部分都是他下面的点),你可能会想如果每次都处理的是自己下面的点,那么隔壁树枝的怎么办呢,由于这是一个分治合并的过程,在树上那么总会有一个汇点处理这一切的。。。
那么现在要找的路径数 就是 把这个颜色的点都去掉,得到了很多的块或者点,每个块内部的路径可以用n×(n-1)/2 得到,然而每个部分都有相应管辖的点.
#include <bits/stdc++.h>
using namespace std;
const int N = 4e5+100;
typedef long long ll;
int c[N],vis[N];///c[i]表示第i个点的颜色,vis[i]表示的是i这个颜色有没有出现过
vector<int> e[N];///存储这个图呢
ll sum[N],size[N];///sum[i]表示的是这个颜色i所能管理的点,size[i]表示的是以i为根的点的个数
ll ans;
void dfs(int x,int y)
{
size[x]=1;/// 指的是x为根的树的点的个数
sum[c[x]]++;/// sum是指 当前颜色的所能管理的点(包括自身的总个数) 那么每种颜色 最后都是一个接近根的值
///到不了根的部分 就要在后面剔除
ll pre=sum[c[x]];/// 指从根到 x ,c[x] 管辖的点的总个数
for(int i=0; i<e[x].size(); i++)
{
if(e[x][i]==y) continue;
dfs(e[x][i],x);
size[x]+=size[e[x][i]];/// 以x为根的树的点的总个数,当前的这个点还要加上他的子数上的点
ll count=size[e[x][i]]-(sum[c[x]]-pre);/// 总的减去被管理的部分 剩下的都是自由的联通块 直接求路径后面剔除
ans=ans+(1LL*count*(count-1))/2;
//printf("%d\n",sum[c[x]]);
sum[c[x]]+=count;/// 加上这些被剔除的,相当于把这些与根节点颜色不一样的点标记成颜色一样的,这样递归往上返回的时候就不会重复计算这些点了
pre=sum[c[x]];///更新这个颜色所能管理的所有的点
}
}
int main()
{
int n,cas=1;
while(scanf("%d",&n)!=EOF)
{
int num=0;
ans=0;
memset(sum,0,sizeof(sum));
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++)
{
e[i].clear();
scanf("%d",&c[i]);
if(!vis[c[i]])
{
vis[c[i]]=1;///标记这个颜色有没有出现过
num++;///不同的颜色数
}
}
for(int i=1; i<n; i++)
{
int u,v;
scanf("%d%d",&u,&v);
e[u].push_back(v);
e[v].push_back(u);
}
dfs(1,0);
ll ANS = 1LL*num*((1LL)*n*(n-1))/2;
/// 因为根只有一种颜色 这里要剔除所有到不了根的颜色
for(int i=1; i<=n; i++)
{
if(vis[i])
{
ll ct=n-sum[i];
ans+=ct*(ct-1)/2;
}
}
printf("Case #%d: %lld\n", cas++, ANS-ans);
}
}
2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)的更多相关文章
- 2017ACM暑期多校联合训练 - Team 6 1003 HDU 6098 Inversion (模拟)
题目链接 Problem Description Give an array A, the index starts from 1. Now we want to know Bi=maxi∤jAj , ...
- 2017ACM暑期多校联合训练 - Team 4 1003 HDU 6069 Counting Divisors (区间素数筛选+因子数)
题目链接 Problem Description In mathematics, the function d(n) denotes the number of divisors of positiv ...
- 2017ACM暑期多校联合训练 - Team 3 1003 HDU 6058 Kanade's sum (模拟)
题目链接 Problem Description Give you an array A[1..n]of length n. Let f(l,r,k) be the k-th largest elem ...
- 2017ACM暑期多校联合训练 - Team 2 1003 HDU 6047 Maximum Sequence (线段树)
题目链接 Problem Description Steph is extremely obsessed with "sequence problems" that are usu ...
- 2017ACM暑期多校联合训练 - Team 4 1004 HDU 6070 Dirt Ratio (线段树)
题目链接 Problem Description In ACM/ICPC contest, the ''Dirt Ratio'' of a team is calculated in the foll ...
- 2017ACM暑期多校联合训练 - Team 9 1005 HDU 6165 FFF at Valentine (dfs)
题目链接 Problem Description At Valentine's eve, Shylock and Lucar were enjoying their time as any other ...
- 2017ACM暑期多校联合训练 - Team 9 1010 HDU 6170 Two strings (dp)
题目链接 Problem Description Giving two strings and you should judge if they are matched. The first stri ...
- 2017ACM暑期多校联合训练 - Team 8 1006 HDU 6138 Fleet of the Eternal Throne (字符串处理 AC自动机)
题目链接 Problem Description The Eternal Fleet was built many centuries ago before the time of Valkorion ...
- 2017ACM暑期多校联合训练 - Team 8 1002 HDU 6134 Battlestation Operational (数论 莫比乌斯反演)
题目链接 Problem Description The Death Star, known officially as the DS-1 Orbital Battle Station, also k ...
随机推荐
- C# 开发人员的函数式编程
摘要:作为一名 C# 开发人员,您可能已经在编写一些函数式代码而没有意识到这一点.本文将介绍一些您已经在C#中使用的函数方法,以及 C# 7 中对函数式编程的一些改进. 尽管 .NET 框架的函数式编 ...
- Underscore.js工具库
Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象. 他解决了这个问题:“如果我面对一个空白的 HTML ...
- 元素定位:selenium消息框处理 (alert、confirm、prompt)
基础普及 alert对话框 .细分三种,Alert,prompt,confirm 1. alert() 弹出个提示框 (确定) 警告消息框 alert 方法有一个参数,即希望对用户显示的文本字符串.该 ...
- C++解析(29):类型识别
0.目录 1.类型识别 2.动态类型识别 3.类型识别关键字 4.小结 1.类型识别 在面向对象中可能出现下面的情况: 基类指针指向子类对象 基类引用成为子类对象的别名 静态类型--变量(对象)自身的 ...
- OSPF与Vlan间通信综合实验小结与端口隔离
总结 本实验模拟实际工作环境的网络拓扑结构,至此终于理解了一部分的配置思路: 一.三层交换机连接路由器的端口配置 图中GE0/0/4应该是配置成access类型,这个时候应该是不带vlan标签的. ...
- Django基于正则表达式的URL(1)
1. 此时,用户只能看到列表,如果用户想查看详细信息,应该再增加程序. 2. 把信息用a标签包起来以后,详细信息就有了可以跳转的功能. . 3. 点击不同的用户名时,获取到不同的信息. 3.1 在ur ...
- BZOJ3771 Triple 【NTT + 容斥】
题目链接 BZOJ3771 题解 做水题放松一下 先构造\(A_i\)为\(x\)指数的生成函数\(A(x)\) 再构造\(2A_i\)为指数的生成函数\(B(x)\) 再构造\(3A_i\)为指数的 ...
- 解题:POI 2018 Prawnicy
题面 网上好像都是堆的做法啊......我这个不算离散化是$O(n)$的说(虽然有一坨vector可能不开O2会爆炸) 题目即是让我们求是否存在一个最长的是不少于$k$个给出区间子集的区间,如果存在输 ...
- php 性能优化之opcache - 让你的php性能提升 50%
性能提升原理:减少文件解析的时间. 我们都知道,程序要运行,得有一个编译或者解析的过程,编译或解析之后的代码才是机器可以运行的. 而 php 是一种解析性语言,在使用php来处理http请求的时候,每 ...
- 怎么用spring cloud service-id 进行调用接口
这里最关键的就是加上@LoadBalanced @SpringBootApplication public class ConsumerMovieApplication { @Bean @LoadBa ...