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 ...
随机推荐
- selenium python (九)对话框处理
#!/usr/bin/python# -*- coding: utf-8 -*-__author__ = 'zuoanvip' from selenium import webdriver #对于对 ...
- Raw-OS源代码分析之消息系统-Queue_Buffer
分析的内核版本号截止到2014-04-15,基于1.05正式版.blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现"???"字样,则是未深究理解部分. Raw-OS官方 ...
- v-model在其它元素以及类型上的用法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Linux和Windows设备驱动架构比较
毕业后一直在学操作系统, 有时候觉得什么都懂了,有时候又觉得好像什么都不懂,但总体来说自认为对操作系统实现机制的了解比周围的人还是要多一些.去年曾花了几个星期的晚上时间断断续续翻译了这篇对Linux和 ...
- CAS原子操作实现无锁及性能分析
CAS原子操作实现无锁及性能分析 Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn.net/chen19870707 ...
- 简单的glib测试(三)
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <locale.h&g ...
- Boost源代码学习---weak_ptr.hpp
weak_ptr是辅助shared_ptr的智能指针. 就像它的名字一样.是个"弱"指针:仅有几个接口.仅能完毕非常少工作.它能够从一个shared_ptr或weak_ptr对象构 ...
- iOS优化策略
之前写的一系列文章或者小经验一直没有时间去整理放在博客上,今天整理出来,之前是写在作业部落,语法是markdown,点击链接浏览,仅供参考,希望对你有帮助. https://www.zybuluo.c ...
- HDU 6138 Fleet of the Eternal Throne 后缀数组 + 二分
Fleet of the Eternal Throne Problem Description > The Eternal Fleet was built many centuries ago ...
- 使用delphi 开发多层应用(十六)使用XMLRPC 实现basic4android 远程调用RTC服务(讲述了RTC的特点,其底层通讯协议是自己封装SOCK 库,与kbmmw 的适合场合不完全一样)
RealThinClient (以下简称RTC) 也是一款delphi 多层开发的框架,由于其底层通讯协议是自己封装SOCK 库,抛弃了 大家诟病的indy,因此表现的非常稳定,效率也非常高, ...