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

我采用栈的方式,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. [Ionic] Align and Size Text with Ionic CSS Utilities

    The Ionic framework provides several built-in CSS Utilities or directives that you can leverage when ...

  2. [HTML 5] More about ARIA Relationships

  3. spark transform系列__sortByKey

    该函数主要功能:通过指定的排序规则与进行排序操作的分区个数,对当前的RDD中的数据集按KEY进行排序,并生成一个SHUFFLEdrdd的实例,这个过程会运行shuffle操作,在运行排序操作前,sor ...

  4. 验证DG最大性能模式下使用ARCH/LGWR及STANDBY LOG的不同情况

    总结:  --两台单实例数据库做DG,数据库版本号10.2.0.1.0 1.主库配置为:arch async,备库无STANDBY LOG. 日志中会有:RFS[4]: No standby redo ...

  5. 【C++】String类中的运算符重载

    模块化设计: 头文件: <span style="font-size:18px;"> #ifndef operator_operator_h #define opera ...

  6. MongoDB 2.6安装

    Workaround to install as a service You can manually install 2.6.0 as a service on Windows from an Ad ...

  7. UVA - 1642 Magical GCD 数学

                                  Magical GCD The Magical GCD of a nonempty sequence of positive integer ...

  8. 点击了一个link button,查看后台调用

    使用F12进行监视 本身是一个linkbutton,可以看到绑定了一个JavaScript <a id="gvStaticConnection_ctl02_fresh" hr ...

  9. 学习 shell —— 条件判断 if 的参数

    1. 文件判断表达式 -e filename:如果 filename 存在(exist),则为真: -d filename:如果 filename 为目录(directory),则为真: -f fil ...

  10. IBM 总架构师:话说程序员的职业生涯

    作者:IBM 软件集团大中华区总架构师 寇卫东 有一些年轻的程序员向我咨询,将来的路应该怎么走?俗话说,条条大路通罗马.不同的路都能走向成功.到底选哪条路,取决于自己的兴趣.可能有程序员会问:如果还没 ...