http://acm.hdu.edu.cn/showproblem.php?pid=4303
算法有时候不是关键 关键在于思维能力
这个题 一遍DFS就可以 不需要多复杂的算法
但是需要较好的思维能力 才能在一遍DFS的情况下搞定左右情况的值
自己是思维就是不行呀 看了提示才过的
但是 不知道是因为 64位整型 和int型 相乘相加时会出问题 还是题目的一些数据大小的范围出问题啦
纠结了n久 最后把一些int 都改成64位 就过了 是不是其他问题我也不知道
这个题我是没法说思路啦 因为我已经挂了 呜呜呜呜呜~~~~~~~~~
代码:
#include<iostream> #include<stdio.h> #include<string.h> #include<queue> #include<cmath> #include<stack> #include<algorithm> #define LL long long using namespace std; const int N=300005; struct node { int uppath; LL num; LL upnum; struct tt *next; }mem[N]; struct tt { int j; int color; struct tt *next; }; struct aa { int x,y; int color; }edge[N]; int value[N]; bool cmp(aa a,aa b) { return a.color>b.color; } void build(int i,int j,int color) { struct tt *t=new tt; t->j=j; t->color=color; t->next=mem[i].next; mem[i].next=t; } void Dele(int n) { for(int i=1;i<=n;++i) mem[i].next=NULL; } void Dfs(int x,int pre,int precolor) { struct tt *t=mem[x].next; mem[x].num=0; mem[x].uppath=1; mem[x].upnum=value[x]; LL ldifsum=0,lsum=0; LL updifsum=0,upsum=0; LL lnum=0; int lcolor=0; while(t!=NULL) { if(t->j==pre) {t=t->next;continue;} Dfs(t->j,x,t->color); if(t->j!=pre&&t->color!=precolor) { mem[x].uppath+=mem[t->j].uppath; mem[x].upnum+=(mem[t->j].upnum+value[x]*mem[t->j].uppath); } if(t->color!=lcolor) { ldifsum=lsum; updifsum=upsum; } mem[x].num+=(value[x]*(mem[t->j].uppath*ldifsum)+(mem[t->j].uppath*value[x])+mem[t->j].upnum); lnum+=(mem[t->j].uppath*updifsum+mem[t->j].upnum*ldifsum); lsum+=mem[t->j].uppath; lcolor=t->color; upsum+=mem[t->j].upnum; t=t->next; } mem[x].num+=lnum; } int main() { //freopen("data.txt","r",stdin); int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;++i) { scanf("%d",&value[i]); } for(int i=0;i<n-1;++i) { scanf("%d %d %d",&edge[i].x,&edge[i].y,&edge[i].color); } sort(edge,edge+n-1,cmp); for(int i=0;i<n-1;++i) { build(edge[i].x,edge[i].y,edge[i].color); build(edge[i].y,edge[i].x,edge[i].color); } Dfs(1,0,0); LL ans=0; for(int i=1;i<=n;++i) { ans+=mem[i].num; } cout<<ans<<endl; Dele(n); } }