题目大意:

你有一棵树,问你距离为二的节点的最大联合权值与联合权值和

分析

在巨佬的提示下得到了思路,这不就是枚举每个点作为中间点,再枚举儿子们。求一下最大值和权值和就好了啊。

#include<bits/stdc++.h>
#define ll long long
const int N=2e6+5,INF=0x3f3f3f3f,mod=10007;
using namespace std;

int n,cnt,ans,maxx;
int w[N],head[N];
struct node
{
    int to,next_;
}e[N<<1];

inline int read()
{
    register int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
    while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();
    return x*f;
}

void add(int u,int v)
{
    e[++cnt].next_=head[u];
    e[cnt].to=v;
    head[u]=cnt;
}

int main()
{
    n=read();
    for(int i=1;i<n;i++)
    {
        int u,v;
        u=read();v=read();
        add(u,v);add(v,u);
    }
    for(int i=1;i<=n;i++) w[i]=read();
    for(int i=1;i<=n;i++)
    {
        int max1=0,max2=0;
        int t1=0,t2=0;
        for(int j=head[i];j;j=e[j].next_)
        {
            if(w[e[j].to]>max1)    max2=max1,max1=w[e[j].to];
            else if(w[e[j].to]>max2)    max2=w[e[j].to];
            t1=(t1+w[e[j].to])%mod;
            t2=(t2+w[e[j].to]*w[e[j].to])%mod;
        }
        t1=t1*t1%mod;
        ans=(ans+t1+mod-t2)%mod;
        if(maxx<max1*max2)maxx=max1*max2;
    }
    printf("%d %d\n",maxx,ans);
    return 0;
}