P1351 聯合權值(樹形dp)
阿新 • • 發佈:2018-10-18
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 intn,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)