HDU 4303 Hourai Jeweled 树dp 所有权利和航点 dfs2次要
意甲冠军:
long long ans = 0;
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++)
ans += F(i,j);
F(i,j)表示i点到j点路径上全部的点权和。
若i->j路径上存在2条相邻边边权同样则 F(i,j) = 0
问:ans的值。
int乘法爆掉了我也醉了。
。。
思路:
和网上的统计边方法不同,这里是用统计点出现的次数来计算
我们计算每一个点i 出现的次数,则答案就是 i的次数*i的点权 => dp[i] * a[i]
而i出现的路径起点和终点有4种
1、i的子孙->i的子孙
2、i的子孙->i
3、i到 (非i的子孙( 即i的祖先节点,兄弟节点和兄弟节点的子孙
4、i的子孙->非i的子孙
所以先计算1,2的情况 ,用dp1[i]记录
3,4的情况用dp2[i]记录
则答案就是 for(int i = 1; i <= n; i++) ans += a[i] * (dp1[i]+dp2[i]);
siz[u] 表示以u为根的子树中有效的节点数,若 u -> v(col = 1) && v -> k(col=1), 则以k为根的子树都不是有效节点
(当中v是u的儿子,k是v的儿子)
mp[u][col]表示以u为根。有效节点中 用颜色为col的边相连的节点个数
- #include <map>
- using namespace std;
- #define N 300100
- struct Edge{
- int to, col, nex;
- }edge[N<<1];
- int head[N], edgenum;
- void init(){memset(head, -1, sizeof head); edgenum = 0;}
- void add(int u, int v, int col){
- Edge E = {v, col, head[u]};
- edge[edgenum] = E;
- head[u] = edgenum++;
- }
- typedef long long ll;
- template <class T>
- inline bool rd(T &ret) {
- char c; int sgn;
- if(c=getchar(),c==EOF) return 0;
- while(c!='-'&&(c<'0'||c>'9')) c=getchar();
- sgn=(c=='-')?-1:1;
- ret=(c=='-')?0:(c-'0');
- while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0');
- ret*=sgn;
- return 1;
- }
- template <class T>
- inline void pt(T x) {
- if(x>9) pt(x/10);
- putchar(x%10+'0');
- }
- int n, k;
- ll dp1[N], dp2[N], a[N];
- int siz[N];
- map<int, int> mp[N], mp2[N];//mp[u][col]表示u子树下 边颜色=col 的有效的点数
- void dfs1(int u, int fa){
- siz[u] = 0; dp1[u] = 0;
- for(int i = head[u]; ~i; i = edge[i].nex) {
- int v = edge[i].to; if(v == fa)continue;
- dfs1(v, u);
- mp[u][edge[i].col] += siz[v] - mp[v][edge[i].col];
- siz[u] += siz[v] - mp[v][edge[i].col];
- }
- ll dou = 0;
- for(int i = head[u]; ~i; i = edge[i].nex) {
- int v = edge[i].to; if(v == fa)continue;
- dou += (ll)(siz[v] - mp[v][edge[i].col]) * (ll)(siz[u] - mp[u][edge[i].col]);
- dp1[u] += siz[v] - mp[v][edge[i].col];
- }
- dp1[u] += dou >> 1;
- siz[u]++;
- }
- void dfs2(int u, int ok, int col, int fa) {
- dp2[u] = (ll)(siz[u] - mp[u][col]) * (ll)ok;
- for(int i = head[u]; ~i; i = edge[i].nex) {
- int v = edge[i].to; if(v == fa)continue;
- if(u != fa && edge[i].col == col)
- dfs2(v, siz[u] - mp[u][edge[i].col], edge[i].col, u);
- else
- dfs2(v, ok + siz[u] - mp[u][edge[i].col], edge[i].col, u);
- }
- }
- void solve(){
- init();
- for(int i = 1; i <= n; i++)rd(a[i]), mp[i].clear(), mp2[i].clear();
- for(int i = 1, u, v, d; i < n; i++) {
- rd(u);rd(v);rd(d);
- add(u,v,d); add(v,u,d);
- }
- dfs1(1, 1);
- dfs2(1, 0, -1, 1);
- }
- int main() {
- while(rd(n)){
- solve();
- ll ans = 0;
- for(int i = 1; i <= n; i++)
- ans += a[i]*(dp1[i]+dp2[i]);
- pt( ans );putchar('\n');
- }
- return 0;
- }
- /*
- 4
- 1 10 100 1000
- 1 2 1
- 2 3 1
- 3 4 1
- 5
- 1 10 100 1000 10000
- 1 2 1
- 2 3 1
- 3 4 1
- 2 5 2
- 11
- 1 2 3 4 5 6 7 8 9 111 123
- 1 2 1
- 1 3 2
- 2 4 3
- 2 5 1
- 3 6 3
- 3 7 3
- 5 8 1
- 5 9 2
- 8 10 1
- 11 8 2
- 14
- 1 2 3 4 5 6 7 8 9 111 123 235 66 1000
- 1 2 1
- 1 3 2
- 2 4 3
- 2 5 1
- 3 6 3
- 3 7 3
- 5 8 1
- 5 9 2
- 8 10 1
- 11 8 2
- 12 11 2
- 8 13 1
- 8 14 2
- 10
- 1 1 1 1 1 1 1 1 1 1
- 1 2 1
- 1 7 1
- 1 10 2
- 2 3 5
- 2 6 4
- 3 4 1
- 3 5 8
- 7 8 2
- 7 9 1
- 14
- 1 2 5 10 20 30 70 80 100 1000 2000 5000 100000 1000000
- 1 2 2
- 1 3 1
- 1 4 1
- 2 5 2
- 2 8 3
- 3 9 3
- 3 6 2
- 4 7 1
- 4 10 3
- 3 11 3
- 6 12 2
- 13 1 2
- 14 3 3
- */
版权声明:本文博客原创文章,博客,未经同意,不得转载。
HDU 4303 Hourai Jeweled 树dp 所有权利和航点 dfs2次要的更多相关文章
- HDU 4303 Hourai Jeweled 解题报告
HDU 4303 Hourai Jeweled 解题报告 评测地址: http://acm.hdu.edu.cn/showproblem.php?pid=4303 评测地址: https://xoj. ...
- HDU 4303 Hourai Jeweled(树形DP)
http://acm.hdu.edu.cn/showproblem.php?pid=4303 题意:给出一棵树,树上的每一个节点都有一个权值,每条边有一个颜色,如果一条路径上相邻边的颜色都是不同的,那 ...
- HDU 1011 Starship Troopers (树dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意: 题目大意是有n个房间组成一棵树,你有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个 ...
- HDU 4661 Message Passing ( 树DP + 推公式 )
参考了: http://www.cnblogs.com/zhsl/archive/2013/08/10/3250755.html http://blog.csdn.net/chaobaimingtia ...
- HDU 4085 斯坦纳树+DP
https://cn.vjudge.net/problem/HDU-4085 给你n,m,k ,分别表示有n个点,m条边,每条边有一个权值,表示修复这条边需要的代价 从前k个点中任取一个使其和后k个点 ...
- HDU 4303 树形DP
Hourai Jeweled Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 163840/163840 K (Java/Others) ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- 【HDU 5647】DZY Loves Connecting(树DP)
pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...
- HDU 2196 Computer (树dp)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2196 给你n个点,n-1条边,然后给你每条边的权值.输出每个点能对应其他点的最远距离是多少 ...
随机推荐
- React Native是一套使用 React 构建 Native app 的编程框架
React Native是一套使用 React 构建 Native app 的编程框架 React Native at first sight what is React Native? 跟据官方的描 ...
- 乐在其中设计模式(C#) - 提供者模式(Provider Pattern)
原文:乐在其中设计模式(C#) - 提供者模式(Provider Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 提供者模式(Provider Pattern) 作者:weba ...
- Effective C++ Item 32 确保你的 public 继承模子里出来 is-a 关联
本文senlie原版的,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:"public继承"意味 is-a.适用于 base classe ...
- Directx11学习笔记【九】 【转】 3D渲染管线
原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即给定场景的描述,包括各个物体的材质.纹理.坐标等,照相 ...
- 联想昭阳e43l笔记本配置
驱动精灵硬件检测报告 版本:2015.3.26.1363(8.1.326.1363)========================================================== ...
- HDU 1085-Holding Bin-Laden Captive!(生成功能)
Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Ja ...
- AutoMapper在ABP框架
AutoMapper在ABP框架中的使用说明 为了说明AutoMapper如何使用,我专门开设了一个专题来讲,如果您还没有查看该专题,请点击这里.既然系统地学习了AutoMapper,那么接下来就是该 ...
- iOS当该装置是水平屏,frame和bounds分别
project那里有两个ViewControllers.间ViewController它是root view controller,红色背景,有一个顶button,点击加载后GreenViewCont ...
- HDU 4896 Minimal Spanning Tree(矩阵高速功率)
意甲冠军: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一 ...
- 【C++知识汇总】运营商 & 运算符重载
[运算符] 在进行运算时,假设右括号的话我们知道先运算哪个,那假设没有括号了.算术运算符,关系运算符,逻辑运算符,位运算符.赋值运算符,++.--运算符等等,那么多的运算符.我们先算哪边 ...