HDU 6035 --- Colorful Tree (Tree DP), hdu6035 --- colorful
Question Link
Problem DescriptionThere 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.
InputThe input contains multiple test cases.
For each test case, the first line contains one positive integers n, indicating the number of nodes. (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.
OutputFor 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 Input31 2 11 22 361 2 1 3 2 11 21 32 42 53 6
Sample OutputCase #1: 6 Case #2: 29 a tree with n nodes numbered from 1 to n, each node has a color ci (1 <= ci <= n). Each path on the tree has a value that indicates the number of color types on the path, now sum all the path values in the tree. Idea: You can change the description of the question, that is, find the number of paths containing the color ci, and then sum all the colors. This is still difficult to calculate. You can reverse consider the number of paths containing color ci = n * (n-1)/2-the number of paths without color ci, the number of paths that do not contain the color ci indicates that the color ci divides the entire tree into connected blocks. For each connected block, if the number of nodes is x, it is C (x, 2), sum all connected blocks. The Code is as follows:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <vector>using namespace std;typedef long long LL;const int N=200005;int c[N],sum[N],sz[N];vector<int> t[N];LL ans;int dfs(int u,int pa){ sz[u]=1; int cn=t[u].size(); for(int i=0;i<cn;i++) { int v=t[u][i]; if(v==pa) continue; int r=sum[c[u]]; sz[u]+=dfs(v,u); int o=sum[c[u]]-r; ans+=(LL)(sz[v]-o)*(LL)(sz[v]-o-1)/2; sum[c[u]]+=sz[v]-o; } sum[c[u]]++; return sz[u];}int main(){ ///cout << "Hello world!" << endl; int n,Case=1; while(scanf("%d",&n)!=EOF) { memset(sum,0,sizeof(sum)); for(int i=1;i<=n;i++){ scanf("%d",&c[i]); t[i].clear(); } for(int i=1;i<n;i++) { int u,v; scanf("%d%d",&u,&v); t[u].push_back(v); t[v].push_back(u); } ans=0; dfs(1,-1); for(int i=1;i<=n;i++) { ans+=(LL)(n-sum[i])*(LL)(n-sum[i]-1)/2; } ans=(LL)n*(LL)(n-1)*(LL)n/2-ans; printf("Case #%d: %lld\n",Case++,ans); } return 0;}