HDU 6035 Colorful Tree (2017多校1

来源:互联网 发布:mac电脑壁纸高清 编辑:程序博客网 时间:2024/06/06 11:22

题意:

给你一棵树, 树上的路权为  这条路上不同颜色的个数。  求所有路径的权值之和。

思路:

感觉好难。。

其实这个题一遍dfs 就可以办了。

可以反过来思考,对于每一种颜色求出 有多少条路 没有经过这个颜色。 最后用总路数减去即可。

令sum[i] 表示 以i 颜色为根的子树总大小。

siz[u]表示以u 为根的子树的大小。


怎么找呢?

假如我们枚举到u结点了。 对于u 的每个孩子, 我们找出他们的sum[col[u] ]   中间的位置差就是一个连通分块, 他们组成的路 都不包含颜色u。

这样把所有孩子都累加起来, 在更新sum[col[u] ]。


但是这样统计 会算出整体sum[col[u] ] 并不是这条链的。

这里的pre 变量就比较巧妙了。

在dfs 这个点之前,我们令pre = sum[ col[u] ] 就是  这个点之前的所有sum[col[u]]

然后更新完u的孩子后的sum[col[u] ]  - pre  就是这条链的。


#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int maxn = 200000 + 10;vector<int>g[maxn];int col[maxn];long long sum[maxn];int siz[maxn];int vis[maxn];int num;long long ans;void dfs(int cur, int fa){    siz[cur] = 1;    int pre = sum[col[cur] ];    bool ok = 0;    for (int i = 0; i < g[cur].size(); ++i){        int v = g[cur][i];        if (v == fa) continue;        ok = 1;        dfs(v, cur);        siz[cur] += siz[v];        long long tmp = siz[v] - (sum[col[cur] ] - pre);        ans += (long long)tmp*(long long)(tmp-1) / 2;        sum[col[cur] ] += tmp;        pre = sum[col[cur] ];    }    sum[col[cur] ] += 1;}int main(){    int n, ks = 0;    while(~scanf("%d",&n)){        memset(vis,0,sizeof vis);        num = ans = 0;        for (int i = 1; i <= n; ++i){            scanf("%d", &col[i]);            if (!vis[col[i] ]){                vis[col[i] ] = 1;                ++num;            }            sum[i] = 0;            g[i].clear();        }        for (int i = 1; i < n; ++i){            int x,y;            scanf("%d %d",&x, &y);            g[x].push_back(y);            g[y].push_back(x);        }        ans = 0;        dfs(1, -1);        for (int i = 1; i <= n; ++i){            if (vis[i]){                long long tmp = siz[1] - sum[i];                ans += tmp * (tmp-1) / 2;            }        }        ans = (long long)num * (long long)n * (long long)(n-1) / 2 - ans;        printf("Case #%d: %I64d\n", ++ks, ans);    }    return 0;}


云上贵州”创新大赛 !

Colorful Tree

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1733    Accepted Submission(s): 713


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(n1)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. (2n200000)

Next line contains n integers where the i-th integer represents ci, the color of node i(1cin)

Each of the next n1 lines contains two positive integers x,y (1x,yn,xy), 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 #xy" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
 

Sample Input
31 2 11 22 361 2 1 3 2 11 21 32 42 53 6
 

Sample Output
Case #1: 6Case #2: 29
 

Source
2017 Multi-University Training Contest - Team 1
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:  6055 6054 6053 6052 6051 
 


原创粉丝点击