不难发现,树中与某个点距离为2的点只可能是它的父亲的父亲、儿子的儿子 或者 兄弟,分类讨论一下即可。
只有对于兄弟我们不能暴力搞,维护一下每个节点的所有儿子的前缀和、前缀MAX就行了。
1 #include<cstdio> 2 #include<algorithm> 3 #include<vector> 4 using namespace std; 5 #define N 200001 6 #define MOD 10007 7 int n; 8 vector<int>G[N],son[N]; 9 typedef long long ll; 10 typedef vector<int>::iterator ITER; 11 int x,y,fa[N],dep[N],maxv,sumv,w[N]; 12 void dfs(int U) 13 { 14 for(ITER it=G[U].begin();it!=G[U].end();it++) 15 if((*it)!=fa[U]) 16 { 17 fa[*it]=U; 18 dep[*it]=fa[U]+1; 19 son[U].push_back(*it); 20 dfs(*it); 21 } 22 } 23 void dfs2(int U) 24 { 25 if(dep[U]>=2) sumv=(sumv+w[U]*w[fa[fa[U]]]%MOD)%MOD; 26 ll All=0,t=0; 27 for(ITER it=son[U].begin();it!=son[U].end();it++) All+=(ll)w[*it]; 28 for(ITER it=son[U].begin();it!=son[U].end();it++) 29 { 30 t+=(ll)w[*it]; 31 sumv=(sumv+w[*it]*(int)(All-t)%MOD)%MOD; 32 dfs2(*it); 33 } 34 } 35 void dfs3(int U) 36 { 37 if(dep[U]>=2) maxv=max(maxv,w[U]*w[fa[fa[U]]]); 38 int t=0; 39 for(int i=0;i<son[U].size();i++) 40 { 41 if(i) 42 { 43 t=max(t,w[son[U][i-1]]); 44 maxv=max(maxv,w[son[U][i]]*t); 45 } 46 dfs3(son[U][i]); 47 } 48 } 49 int main() 50 { 51 scanf("%d",&n); 52 for(int i=1;i<n;i++) 53 { 54 scanf("%d%d",&x,&y); 55 G[x].push_back(y); 56 G[y].push_back(x); 57 } 58 for(int i=1;i<=n;i++) scanf("%d",&w[i]); 59 dfs(1); dfs2(1); dfs3(1); 60 printf("%d %d ",maxv,(sumv<<1)%MOD); 61 return 0; 62 }