码迷,mamicode.com
首页 > 其他好文 > 详细

hdu-6035 Colorful Tree

时间:2017-08-01 21:46:25      阅读:163      评论:0      收藏:0      [点我收藏+]

标签:总数   维护   push   hdu   ios   space   const   tree   cout   

题目意思是计算所有路径(n*(n-1)/2)经过的不同颜色的数目和。

这个数目和可以转化为每种颜色经过的路径数目的求和,而这个求和又等价于颜色总数*n*(n-1)/2-没有经过某种颜色的边的数量的求和。

没有结果某种颜色的数量等价于由此颜色的节点将树拆分出多个联通块,每个联通块的节点数为k,则边数为k*(k-1)/2。

#include <iostream>
#include <vector>
#include <set>
#define LL long long
using namespace std;
int n;
const int N = 200050;
vector<int> g[N];
LL sum[N];//维护以某种颜色为根的子树和
int colors[N];
bool vis[N];
LL wayCnt;
void init()
{
    fill(vis, vis + n + 1, 0);
    fill(sum, sum + n + 1, 0);
    for (int i = 0; i <= n; i++) g[i].clear();
    wayCnt = 0;
}
LL dfs(int now)
{
    int col = colors[now];
    sum[col]++;
    LL preSum = sum[col];//用以计算当前点到某子树之间的联通块大小
    vis[now] = 1;
    LL nowTreeSize = 1;
    int fuck = 0;
    for (int i = 0; i < g[now].size(); i++)
    {
        int nx = g[now][i];
        if (vis[nx]) continue;
        LL siz=dfs(nx);
        LL change = sum[col] - preSum;//计算出底层增量
        LL blockSize = siz - change;
        //cout << now << ": " << blockSize << endl;
        sum[col] += blockSize;
        preSum = sum[col];
        fuck += blockSize;
        wayCnt += blockSize*(blockSize - 1) / 2;
        nowTreeSize += siz;
    }
    return nowTreeSize;
}
int main()
{
    cin.sync_with_stdio(false);
    int cas = 1;
    while (cin >> n)
    {
        set<int> cc;
        for (int i = 1; i <= n; i++)
            cin >> colors[i],cc.insert(colors[i]);
        init();
        for (int i = 0; i < n-1; i++)
        {
            int a, b;
            cin >> a >> b;
            g[a].push_back(b);
            g[b].push_back(a);
        }
        dfs(1);
        //cout << wayCnt << endl;
        for (int i = 1; i <=n; i++)
        {
            if (cc.find(i)!=cc.end()&&i != colors[1])
            {
                LL blockSize = n - sum[i];
                wayCnt += blockSize*(blockSize - 1) / 2;
            }
        }
        cout << "Case #" << cas++ << ": ";
        cout << cc.size()*n*(n-1)/2-wayCnt << endl;
    }
    return 0;
}

 

hdu-6035 Colorful Tree

标签:总数   维护   push   hdu   ios   space   const   tree   cout   

原文地址:http://www.cnblogs.com/LukeStepByStep/p/7270676.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!