说实话,挺复杂的一道题。

我采用栈的方式,DFS在搜索完一个节点的所有子结点后,通过排序,加快计算该结点所有可能的路径:子结点与子结点的连通,子结点与父结点的连通,通过父结点与各祖先结点的连通。同时记录路径数计算。思路清晰就能写出来了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define LL __int64
const int N=300010;
using namespace std; struct e{
int u,v;
int col;
int next;
}edge[N*2];
int head[N];
int tot;
int val[N];
struct p{
LL valsum;
LL route;
int col;
}DFST[N],pre,aft;
LL tmp; void addedge(int u,int v,int col){
edge[tot].u=u;
edge[tot].v=v;
edge[tot].col=col;
edge[tot].next=head[u];
head[u]=tot++;
edge[tot].u=v;
edge[tot].v=u;
edge[tot].col=col;
edge[tot].next=head[v];
head[v]=tot++;
} bool cmp(p a, p b){
if(a.col<b.col) return true;
return false;
} void dfs(LL &ans,int parent,int now,int parent_col,LL &route,int pos){
int k=-1; LL son_val,son_route;
for(int ei=head[now];ei!=-1;ei=edge[ei].next){
if(edge[ei].v==parent) continue;
k++; son_val=son_route=0;
dfs(son_val,now,edge[ei].v,edge[ei].col,son_route,pos+k);
DFST[pos+k].valsum=son_val; DFST[pos+k].route=son_route;
DFST[pos+k].col=edge[ei].col;
}
if(k>=0){
sort(DFST+pos,DFST+pos+k+1,cmp);
for(int i=0;i<=k;i++){
if(parent!=-1)
tmp+=((LL)DFST[pos+i].valsum+(LL)val[now]*DFST[pos+i].route);
if(DFST[pos+i].col!=parent_col){
ans+=((LL)DFST[pos+i].valsum+(LL)val[now]*DFST[pos+i].route);
route+=(LL)DFST[pos+i].route;
}
}
if(parent!=-1){
ans+=val[now];
route++;
}
if(DFST[pos+k].col!=DFST[pos].col){
pre=DFST[pos];
int c=DFST[pos].col;
for(int i=1;i<=k;i++){
if(DFST[pos+i].col==c){
pre.valsum=pre.valsum+DFST[pos+i].valsum;
pre.route=pre.route+DFST[pos+i].route;
}
else{
aft=DFST[pos+i];
int si=i+1;
while(aft.col==DFST[pos+si].col&&si<=k){
aft.valsum+=DFST[pos+si].valsum;
aft.route+=DFST[pos+si].route;
si++;
}
i=si-1;
tmp+=(pre.route*aft.valsum+aft.route*pre.valsum+(pre.route*aft.route)*val[now]);
pre.route+=aft.route;
pre.valsum+=aft.valsum;
c=aft.col;
}
}
}
}
else{
ans=val[now];
route=1;
}
} int main(){
int n,u,v,c;
while(scanf("%d",&n)!=EOF){
tmp=0;
for(int i=1;i<=n;i++)
scanf("%d",&val[i]);
memset(head,-1,sizeof(head));
tot=0;
for(int i=1;i<n;i++){
scanf("%d%d%d",&u,&v,&c);
addedge(u,v,c);
}
LL ans=0,route=0;
dfs(ans,-1,1,-1,route,0);//sum,parent,nownode,parent_col,route,beginpos
printf("%I64d\n",ans+tmp);
}
return 0;
}

  

HDU 4303 Contest 1的更多相关文章

  1. HDU 4303 Hourai Jeweled 解题报告

    HDU 4303 Hourai Jeweled 解题报告 评测地址: http://acm.hdu.edu.cn/showproblem.php?pid=4303 评测地址: https://xoj. ...

  2. HDU 4303 Hourai Jeweled(树形DP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4303 题意:给出一棵树,树上的每一个节点都有一个权值,每条边有一个颜色,如果一条路径上相邻边的颜色都是不同的,那 ...

  3. HDU 5045 Contest(状压DP)

    Problem Description In the ACM International Collegiate Programming Contest, each team consist of th ...

  4. hdu - 5045 - Contest(国家压缩dp)

    意甲冠军:N个人M通过主打歌有自己的期望,每个问题发送人玩.它不能超过随机播放的次数1,追求最大业绩预期 (1 ≤ N ≤ 10,1 ≤ M ≤ 1000). 主题链接:pid=5045" ...

  5. [ACM] hdu 5045 Contest (减少国家Dp)

    Contest Problem Description In the ACM International Collegiate Programming Contest, each team consi ...

  6. HDU 4303 树形DP

    Hourai Jeweled Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 163840/163840 K (Java/Others) ...

  7. HDU–5988-Coding Contest(最小费用最大流变形)

    Coding Contest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  8. hdu 5045 Contest(状态压缩DP)

    题解:我们使用一个二位数组dp[i][j]记录进行到第i个任务时,人组合为j时的最大和(这里的j我们用二进制的每位相应一个人). 详细见代码: #include <iostream> #i ...

  9. 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, ...

随机推荐

  1. 今天又犯了Java/Scala里面substring的错误

    每次都误以为是 substring(startIndex, length) 其实是 substring(startIndex, endIndex) 嗯 Java/Scala 跟 C++ 是不一样的.

  2. [HTML 5] Atomic Relevant Busy

    Together 'aria-live', we can use 'aria-atomic', 'aria-relevant' and 'aria-busy' to give more informa ...

  3. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第3章节--SharePoint 2013 开发者工具 用SPD开发SharePoint应用程序

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第3章节--SharePoint 2013 开发者工具 用SPD开发SharePoint应用程序         非常多开 ...

  4. 《AndroidStudio每日一贴》3.高速切换代码风格、配色方案和键盘

    <AndroidStudio每日一贴>3.高速切换代码风格.配色方案和键盘 高速切换代码风格.配色方案和键盘,使用快捷键: control + ~ 很多其它有用技巧请查看<Andro ...

  5. 开发效率必备之Mac双屏显示

    自从2015年9月苹果公布EI Captain,带来了一个新的功能,叫做分屏,也就是在一块屏幕上分成左右两部分,能够分别进行操作,互不影响. 例如以下图所看到的: watermark/2/text/a ...

  6. [寒江孤叶丶的Cocos2d-x之旅_33]RichTextEx一款通过HTML标签控制文字样式的富文本控件

    RichTextEx一款通过HTML标签控制文字样式的富文本控件 原创文章,欢迎转载.转载请注明:文章来自[寒江孤叶丶的Cocos2d-x之旅系列] 博客地址:http://blog.csdn.net ...

  7. iOS-UIApplication详解

    UIApplication简介 UIApplication对象是应用程序的象征. 每一个应用程序都有自己的UIApplication对象,而且是单例. 一个iOS程序启动后创建的第一个对象就是UIAp ...

  8. 杂项-DB-分布式:HBase

    ylbtech-杂项-DB-分布式:HBase HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文“Bigtable:一个结构化数据的分布式存储系 ...

  9. Jenkins+Docker部署Maven聚合工程

    这几天,把公司的预发布环境,改成docker部署,遇到了一些坑,有jenkins里的部署脚本的问题,也有harbor仓库的问题,还有docker远程访问的问题,还有DooD....一堆坑 Jenkin ...

  10. Git 学习笔记(一)

    某大牛曾经说过,版本控制的最大好处就是让你可以永远后悔,而 Git 无疑是众多版本控制软件当中的佼佼者,在开源社区更是备受青睐,那么它为何会诞生,和其他的版本控制软件项目又有什么不同?且让我们慢慢来看 ...