【洛谷P1351】联合权值

我们枚举中间点,当连的点数不小于2时进行处理

最大值好搞

求和:设中间点 i 所连所有点权之和为sum

则对于每个中间点i的联合权值之和为:

w[j]*(sum-w[j])之和

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 const int p=10007,N=200010,M=400020;
 5 int head[M],next[M],to[M],du[N],a[N],size;
 6 int w[N],n,sum,ss,m1,m2,ans1,ans2;
 7 void uni(int x,int y){
 8     size++;
 9     du[x]++;
10     next[size]=head[x];
11     head[x]=size;
12     to[size]=y;
13 }
14 int main(){
15     int x,y,q;
16     size=ans1=0;
17     scanf("%d",&n);
18     for (int i=1;i<n;i++){
19         scanf("%d %d",&x,&y);
20         uni(x,y);
21         uni(y,x);
22     }
23     for (int i=1;i<=n;i++)
24         scanf("%d",&w[i]);
25     for (int x=1;x<=n;x++){
26         if (du[x]<2) 
27             continue;
28         m1=m2=sum=q=ss=0;
29         for (int e=head[x];e;e=next[e]){
30             int y=to[e];
31             sum=(sum+w[y])%p;
32             a[++q]=y;
33             if (w[y]>m1){
34                 m2=m1;
35                 m1=w[y];
36             }
37             else if (w[y]>m2)
38                 m2=w[y];
39         }
40         if (m1*m2>ans1)
41             ans1=m1*m2;
42         for (int j=1;j<=q;j++)
43             ans2=(ans2+w[a[j]]*(sum-w[a[j]]+p)%p)%p;
44     }
45     printf("%d %d",ans1,ans2);
46     return 0;
47 }
STD

 

转载于:https://www.cnblogs.com/Absolute-Zero/p/6018523.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值