HDU 4303 Contest 1
说实话,挺复杂的一道题。
我采用栈的方式,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的更多相关文章
- 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 5045 Contest(状压DP)
Problem Description In the ACM International Collegiate Programming Contest, each team consist of th ...
- hdu - 5045 - Contest(国家压缩dp)
意甲冠军:N个人M通过主打歌有自己的期望,每个问题发送人玩.它不能超过随机播放的次数1,追求最大业绩预期 (1 ≤ N ≤ 10,1 ≤ M ≤ 1000). 主题链接:pid=5045" ...
- [ACM] hdu 5045 Contest (减少国家Dp)
Contest Problem Description In the ACM International Collegiate Programming Contest, each team consi ...
- HDU 4303 树形DP
Hourai Jeweled Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 163840/163840 K (Java/Others) ...
- HDU–5988-Coding Contest(最小费用最大流变形)
Coding Contest Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- hdu 5045 Contest(状态压缩DP)
题解:我们使用一个二位数组dp[i][j]记录进行到第i个任务时,人组合为j时的最大和(这里的j我们用二进制的每位相应一个人). 详细见代码: #include <iostream> #i ...
- 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, ...
随机推荐
- 洛谷—— P3353 在你窗外闪耀的星星
https://www.luogu.org/problem/show?pid=3353 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年 ...
- Unity里包裹Debug,且不影响Debug的重定向
Debug.Log, Debug.LogWarning, Debug.LogError在project中常常须要再包裹一层.做些定制.也方便开关Log.但有一个问题时.当用一个类将Debug包裹起来后 ...
- HDU 4268 Alice and Bob(贪心+Multiset的应用)
题意: Alice和Bob有n个长方形,有长度和宽度,一个矩形能够覆盖还有一个矩形的条件的是,本身长度大于等于还有一个矩形,且宽度大于等于还有一个矩形.矩形不可旋转.问你Alice最多能覆盖Bo ...
- 页面与后台传递中文乱码问题(java乱码)
1.前台中文传递到后台乱码. 前台不须要处理, 系统一般都会默认把中文转化为ISO-8859-1类型. 仅仅需在后台接受数据是处理 Str为前台传过来的中文字符串: String inputer = ...
- fgets()函数和sscanf()函数的使用方法
fgets 百度百科:从文件结构体指针stream中读取数据,每次读取一行.读取的数据保存在buf指向的字符数组中.每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),假设文件里 ...
- Java-杂项: Java中Array和ArrayList区别
ylbtech-Java-杂项: Java中Array和ArrayList区别 1.返回顶部 1. 1)精辟阐述:可以将 ArrayList想象成一种“会自动扩增容量的Array”. 2)Array( ...
- Java-MyBatis-杂项: MyBatis 中 in 的用法2
ylbtech-Java-MyBatis-杂项: MyBatis 中 in 的用法2 1.返回顶部 1. 一.简介 在SQL语法中如果我们想使用in的话直接可以像如下一样使用: select * fr ...
- 列表查询组件代码, 简化拼接条件SQL语句的麻烦
列表查询组件代码, 简化拼接条件SQL语句的麻烦 多条件查询
- mysql面试几个问题
1.为什么InnoDB表最好要有自增列做主键? InnoDB引擎表是基于B+树的索引组织表(IOT) 关于B+树 (图片来源于网上) B+ 树的特点: a.所有关键字都出现在叶子结点的链表中(稠密索引 ...
- ZBrush中如何对模型进行减面操作
Decimation Master是ZBrush 4R8自带的一个插件.中文名叫减面大师.其功能非常强大,也非常的方便,可以帮助我们提高效率,减少电脑资源损耗.作为一名3D美术师是必须掌握的一个技术. ...