1. 程式人生 > >P1351 聯合權值(樹形dp)

P1351 聯合權值(樹形dp)

style gis nbsp color dfs sin .... 狀況 ...

P1351 聯合權值

想刷道水題還交了3次.....丟人

(1.沒想到有兩個點都是兒子的狀況 2.到處亂%(大霧))

先dfs一遍處理出父親$fa[x]$

藍後再一遍dfs,搞搞就出來了。

#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
using namespace std;
const int p=10007;
int max(int &a,int &b){return a>b?a:b;}
#define N 200002 
int
n,fa[N],val[N],f1[N],f2[N]; int cnt,hd[N],nxt[N<<1],ed[N],poi[N<<1]; void adde(int x,int y){ nxt[ed[x]]=++cnt; hd[x]=hd[x]?hd[x]:cnt; ed[x]=cnt; poi[cnt]=y; } void dfs1(int x,int ffa){//處理fa數組 fa[x]=ffa; for(int i=hd[x];i;i=nxt[i]) if(poi[i]!=ffa) dfs1(poi[i],x); }
void dfs2(int x){ int mxd=0,tot=0; for(int i=hd[x];i;i=nxt[i]){ int to=poi[i]; if(to==fa[x]) continue; f1[x]=max(f1[x],val[to]*mxd); f2[x]=1ll*(f2[x]+val[to]*tot)%p; mxd=max(mxd,val[to]);//以上為構成聯合權值的2個點都是兒子的情況 tot=(tot+val[to])%p; dfs2(to); f1[x]
=max(f1[x],f1[to]); f2[x]=1ll*(f2[x]+f2[to])%p; } int g=fa[fa[x]],v=val[x]*val[g];//點x和x的爺爺構成聯合權值 f1[g]=max(f1[g],v); f2[g]=1ll*(f2[g]+v)%p; } int main(){ scanf("%d",&n); int q1,q2; for(int i=1;i<n;++i){ scanf("%d%d",&q1,&q2); adde(q1,q2); adde(q2,q1); } for(int i=1;i<=n;++i) scanf("%d",&val[i]); dfs1(1,0); dfs2(1); f2[1]=1ll*f2[1]*2%p;//記得*2 printf("%d %d",f1[1],f2[1]); return 0; }

P1351 聯合權值(樹形dp)