洛谷 P1351 联合权值

首先题意很明显,所谓“图”其实是一棵树。但这个性质意义在于给\(dalao\)一些秀树形结构的机会,顺便说明图很稀疏,而并不会引导解题。

如果从图的角度看,很明显就是枚举“中间点”,再枚举与之相连的两个点。复杂度\(O(\sum_{i\in V} e_i\,^2)\)即度数的平方和。T三个点。

再优化每次求答案的过程,加预处理:对于中间点\(i\)的一个相连点\(j\),它会与和\(i\)相连的其他点求联合权值,相当于\(W_j\times(\sum W_p-Wj)\),其中\(p\)是与\(i\)相连的点。把每个点\(i\)对应的\(\sum W_p\)预先求出,\(O(n)\)求和。

每个点最大值就用最大权值乘次大权值求出。

#include<iostream>
#include<vector>
using namespace std;
vector<long long> a[200001];
long long n,u,v,max1,max2,AnsMax,AnsSum,w[200001],pre[200001];
int main()
{
    cin>>n;
    for(int i=1;i<=n-1;i++)
    {
        cin>>u>>v;
        a[u].push_back(v),a[v].push_back(u);
    }
    for(register int i=1;i<=n;i++)
        cin>>w[i];
    for(register int i=1;i<=n;i++)
        for(register int j=0;j<a[i].size();j++)
            pre[i]+=w[a[i][j]];
    for(register int i=1;i<=n;i++)
    {
        max1=max2=0;
        for(register int j=0;j<a[i].size();j++){
            u=w[a[i][j]]*(pre[i]-w[a[i][j]]);
            AnsSum=(AnsSum+u)%10007;
            if(w[a[i][j]]>max1) max2=max1,max1=w[a[i][j]];
            else if(w[a[i][j]]>max2) max2=w[a[i][j]];
        }
        AnsMax=max(AnsMax,max1*max2);
    }
    cout<<AnsMax<<' '<<AnsSum;
    return 0;
}

转载于:https://www.cnblogs.com/ehznehc/p/10946330.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值