做法:DFS,树的深度优先遍历
思路:
距离为2的点对有两种:
1.自己的儿子们之间
2.自己的父亲和自己的儿子们
对树进行一遍dfs后得出max和sum
因为是求有序点对(dfs是从上到下,然而有序对也可以是从下往上),所以结果需要*2
代码
#include <bits/stdc++.h> using namespace std; #define pb push_back #define mp(aa,bb) make_pair(aa,bb) #define _for(i,b) for(int i=(0);i<(b);i++) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define per(i,b,a) for(int i=(b);i>=(a);i--) #define mst(abc,bca) memset(abc,bca,sizeof abc) #define X first #define Y second #define lowbit(a) (a&(-a)) typedef long long ll; typedef pair<int,int> pii; typedef unsigned long long ull; typedef long double ld; const int N=2e5+10; const int INF=0x3f3f3f3f; const int mod=10007; const double eps=1e-6; const double PI=acos(-1.0); int n,w[N],Max,Sum; vector<int> g[N]; void dfs(int u,int fa){ int sumson=0,maxson=0; for(int v:g[u]){ if(v==fa) continue; dfs(v,u); //自己(u)的儿子们(v) Max=max(Max,w[v]*maxson); Sum+=w[v]*sumson; Sum%=mod; sumson+=w[v]; sumson%=mod; maxson=max(maxson,w[v]); } //自己(u)父亲(fa)和自己儿子们(v) Max=max(Max,w[fa]*maxson); Sum+=w[fa]*sumson; Sum%=mod; } void solve(){ cin>>n; _for(i,n-1){ int u,v;cin>>u>>v; g[u].pb(v);g[v].pb(u); } rep(i,1,n) cin>>w[i]; dfs(1,0); cout<<Max<<" "<<Sum*2%mod<<"\n"; } int main(){ ios::sync_with_stdio(0); cin.tie(0); #ifdef DEBUG freopen("F:/laji/1.in", "r", stdin); // freopen("F:/laji/2.out", "w", stdout); #endif // int t;cin>>t;while(t--) solve(); return 0; }