题目描述
思路
用vector存储图,相当于邻接表吧。
然后每个点开始枚举,这个点的其中两个两个邻接点就满足题目要求的距离为2。
求最大联合权值的时候,就可以用mmx记录下遍历i点的第j个邻接点之前的最大权值的邻接点的权值,即mmx=(mmx,w[v[i][j]]),那么到第i个点的最大联合权值就可以记录为mmx*v[i][j]状态转移方程为mx=(mx,mmx*w[v[i][j]])。
就算所有联合权值之和的话,就可以用式子推导,自己写一下就行,举个例子0+1x2+(1+2)x3+(1+2+3)x4加的式子 。
然后注意一下取模即可。
代码
#include <bits/stdc++.h>
#define N 1000005
#define mod 10007
using namespace std;
vector<int> v[N];
typedef long long ll;
int w[N];
int ans=0,mx=0,v1,v2,n;
int main(){
cin>>n;
for(int i=0;i<n-1;i++){
cin>>v1>>v2;
v[v1].push_back(v2);
v[v2].push_back(v1);
}
for(int i=1;i<=n;i++) cin>>w[i];
for(int i=1;i<=n;i++){
int sum=0,mmx=0;
for(auto k:v[i]){
ans+=sum*w[k];
ans%=mod;
sum+=w[k];
sum%=mod;//举个例子 0+1x2+(1+2)x3+(1+2+3)x4加的式子 ,求全体和
mx=max(mx,mmx*w[k]);
mmx=max(mmx,w[k]);//邻接点中的最大权值
}
}
cout<<mx<<" "<<(2ll*ans)%mod<<endl;
return 0;
}