HDU6035:Colorful Tree(树形DP)
传送门
题意
给出一棵最小生成树及每个节点的颜色,询问\(\frac{n(n-1)}2\)条路径的权值和,一条路径的权值为该路径的颜色种数
分析
勉强理解了ftae的做法,但是代码还是不太会,还是太弱了(⊙﹏⊙)。
基本思想:求出每种颜色经过的路径数。
做一定转化:总路径数-每种颜色未经过的路径数
那么未经过的路径数如何求呢?借用虚树的思想,对于颜色c[i],将颜色为c[i]的节点从树上删去,这样树就变成了一个个联通块/节点,未经过的路径数为联通块自身路径数之和,比如一个4个节点的联通块路径数即为12.
那么难度在于如何实现统计操作。我们设置sons[i]代表第i个节点的子树大小,sum[i]代表颜色i已经合并的节点数
那么ct=sons[v]-sum[c[u]]+pre是什么?
它是从当前点 v 到下面每条链下最近的颜色为 c[u] 的节点之间的节点的数量
(请仔细思考)
而这些节点未被合并到sum[c[u]]中,故它为一个联通块,统计该联通块的路径数。
注意到 pre 的初始值为 sum[c[u]] ,也就是说 −sum[c[u]]+pre 保证我们算的是当前这颗子树下的未被合并的节点数量(因为我们前面可能先遍历了其它子树)(请仔细思考)
感谢ftae的题解
trick
代码
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define F(i,a,b) for(int i=a;i<=b;++i)
#define R(i,a,b) for(int i=a;i<b;++i)
#define mem(a,b) memset(a,b,sizeof(a))
const int N = 200200;
int cas;
int n,c[N];
int vis[N];//第i种颜色是否出现
vector<int>vec[N];
ll s;//记录在向上合并的过程中某个颜色在其未出现的块里能形成多少条路径
ll sum[N];//第i中颜色已合并的节点数
int sons[N];//节点i的子树大小
void dfs(int fa,int u)
{
sons[u]=1;
sum[c[u]]++;//合并u
ll pre=sum[c[u]];//已合并的节点数
int sz=vec[u].size();
R(i,0,sz)
{
int v=vec[u][i];
if(v!=fa)
{
dfs(u,v);
sons[u]+=sons[v];//将v子树节点数加入到u子树节点统计中
ll ct=sons[v]-sum[c[u]]+pre;
s+=1LL*ct*(ct-1)/2;
sum[c[u]]+=ct;//合并v子树下的节点
pre=sum[c[u]];
}
}
}
int main()
{
while(~scanf("%d",&n))
{
s=0;
mem(sum,0);mem(vis,0);
int num=0;
F(i,1,n)
{
scanf("%d",c+i);
if(!vis[c[i]]) { num++;vis[c[i]]=1; }
vec[i].clear();
}
int u,v;
R(i,1,n)//建树
{
scanf("%d %d",&u,&v);
vec[u].push_back(v);
vec[v].push_back(u);
}
dfs(0,1);
ll ans=1LL*num*n*(n-1)/2-s;
F(i,1,n) if(vis[i])
{
ll ct=n-sum[i];
ans-=ct*(ct-1)/2;
}
printf("Case #%d: %I64d\n", ++cas,ans);
}
return 0;
}
HDU6035:Colorful Tree(树形DP)的更多相关文章
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
/** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...
- HDU-6035 Colorful Tree(树形DP) 2017多校第一场
题意:给出一棵树,树上的每个节点都有一个颜色,定义一种值为两点之间路径中不同颜色的个数,然后一棵树有n*(n-1)/2条 路径,求所有的路径的值加起来是多少. 思路:比赛的时候感觉是树形DP,但是脑袋 ...
- 熟练剖分(tree) 树形DP
熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...
- hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)
题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others) Memory Limit: ...
- CF 461B Appleman and Tree 树形DP
Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...
- codeforces 161D Distance in Tree 树形dp
题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...
- 5.10 省选模拟赛 tree 树形dp 逆元
LINK:tree 整场比赛看起来最不可做 确是最简单的题目. 感觉很难写 不过单独考虑某个点 容易想到树形dp的状态. 设f[x]表示以x为根的子树内有黑边的方案数. 白边方案只有一种所以不用记录. ...
- Codeforces Round #263 Div.1 B Appleman and Tree --树形DP【转】
题意:给了一棵树以及每个节点的颜色,1代表黑,0代表白,求将这棵树拆成k棵树,使得每棵树恰好有一个黑色节点的方法数 解法:树形DP问题.定义: dp[u][0]表示以u为根的子树对父亲的贡献为0 dp ...
- codeforces Round #263(div2) D. Appleman and Tree 树形dp
题意: 给出一棵树,每个节点都被标记了黑或白色,要求把这棵树的其中k条变切换,划分成k+1棵子树,每颗子树必须有1个黑色节点,求有多少种划分方法. 题解: 树形dp dp[x][0]表示是以x为根的树 ...
- POJ 2486 Apple Tree(树形DP)
题目链接 树形DP很弱啊,开始看题,觉得貌似挺简单的,然后发现貌似还可以往回走...然后就不知道怎么做了... 看看了题解http://www.cnblogs.com/wuyiqi/archive/2 ...
随机推荐
- 怎样改动X-code中的字体大小、颜色
- 关于android 使用bitmap的OOM心得和解决方式
android开发,从2010年開始学习到如今的独立完毕一个app,这漫长的四年,已经经历了非常多次bug的折磨.无数次的加班训练.然而,自以为自己已经比較了解android了,却近期在一个项目上.由 ...
- Python——正則表達式(2)
本文译自官方文档:Regular Expression HOWTO 參考文章:Python--正則表達式(1) 全文下载 :Python正則表達式基础 ======================== ...
- Cocos2d-x 精灵碰撞检測(方法一)
声明函数碰撞检測函数,两个精灵和重写update bool isCollision( CCPoint p1,CCPoint p2,int w1,int h1,int w2,int h2 ); CCSp ...
- HDU 1022 Train Problem I (数据结构 —— 栈)
Problem Description As the new term comes, the Ignatius Train Station is very busy nowadays. A lot o ...
- 翻译:A Tutorial on the Device Tree (Zynq) -- Part I
A Tutorial on the Device Tree (Zynq) -- Part I 此教程的目的 本教程是针对Xilinx' Zynq-7000 EPP设备(一个集成了FPGA的ARM Co ...
- Arcgis Engine(ae)接口详解(1):featureClass
//IFeatureClass 来源请自行解决 IFeatureClass featureClass = null; //获取featureClass的各种名称 //PS:featureClass可以 ...
- Python调用C/Fortran混合的动态链接库--中篇
接下来,介绍一个简单的例子,从fortran中传递并返回一维自定义结构体数组到python注意点:1.fortran新标准支持可分配数组作为变量传入并在subroutine或function分配后返回 ...
- Unity3D游戏开发之粒子系统实现具体解释
今天为大家分享的是Unity3D中的粒子系统.粒子系统通经常使用来表现烟雾.云等高级效果.是一个十分注重制作技巧的部分.今天我们将以一个气泡的演示实例来一起学习怎样在Unity3D中使用粒子系统 ...
- BZOJ 1042: [HAOI2008]硬币购物 容斥+背包
1042: [HAOI2008]硬币购物 Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请 ...