联合权值

25 篇文章 0 订阅
1 篇文章 0 订阅

考虑一下,对于一个中节点,他的联合全职是所有临界点自由组合的和,也就是a*b+b*c+…..
这个值与a+b+c+。。。。有什么关系呢
2*a*b+2*b*c=(a+b+c+…)^2-a*a+b*b+c*c……
而最大的,是最大值与次大值的组合
所以预处理处所有临界点的和,平方和,最大值次大值就行了O(n)复杂度

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define ll long long
int n;
const int M=210000;
long long head[M],nex[M*2],to[M*2],tot,ans,w[M],maxx,maxn[M],max2[M],xx[M],yy[M],sum[M],s[M];
void add(int x,int y){
    nex[++tot]=head[x];
    to[tot]=y;
    head[x]=tot;
}

int main(){

    scanf("%d",&n);
    for(int i=1;i<n;i++){

        scanf("%d%d",&xx[i],&yy[i]);

        //add(x[i],y[i]);
        //add(y[i],x[i]);
    }

    for(int i=1;i<=n;i++) scanf("%d",&w[i]);
    for(int i=1;i<=n;i++) {

    }
    for(int i=1;i<=n;i++){
        int x=xx[i],y=yy[i];
        if(w[y]>max2[x]) max2[x]=w[y];
        if(max2[x]>maxn[x]) swap(maxn[x],max2[x]);
        if(w[x]>max2[y]) max2[y]=w[x];
        if(max2[y]>maxn[y]) swap(maxn[y],max2[y]);
        sum[x]+=w[y];
        s[x]+=w[y]*w[y];
        sum[y]+=w[x];
        s[y]+=w[x]*w[x];
    }
    for(int i=1;i<=n;i++) (sum[i]=1ll*sum[i]*sum[i]-s[i])%10007,ans=(ans+sum[i])%10007,maxx=max(maxx,maxn[i]*max2[i]);




    printf("%d %d",maxx,ans);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值