[P1351][NOIP2014]联合权值

来源:互联网 发布:小程序跳转到淘宝app 编辑:程序博客网 时间:2024/05/17 23:10

原题链接

一开始
并没有想到正解
打了个70分的暴力

然后正解是
枚举中间点
与它相邻的两个点一定符合条件
把这些点的权值加起来平方
再减去他们平方的和
就是sum
再找两个最大权值的点
就是maxn

#include<iostream>#include<cstdio>#include<ctime>#include<algorithm>#include<climits>#include<cstring>#include<cstdlib>#include<queue>#include<cmath>#define MOD 10007#define LL long longusing namespace std;int cnt,num[400005],nxt[400005],head[400005],sum,tmp,w[200005],n,maxn,ans,max1,max2;void add(int p1,int p2){    cnt++;    num[cnt]=p2;    nxt[cnt]=head[p1];    head[p1]=cnt;}int main(){    int i,j,v,u;    scanf("%d",&n);    for(i=1;i<n;i++)    {        scanf("%d%d",&u,&v);        add(u,v);add(v,u);    }    for(i=1;i<=n;i++) scanf("%d",&w[i]);    for(i=1;i<=n;i++)    {        max1=0;max2=0;sum=0;tmp=0;        for(j=head[i];j;j=nxt[j])        {            sum=(sum+w[num[j]])%MOD;            tmp=(tmp+w[num[j]]*w[num[j]])%MOD;            if(w[num[j]]>=max1)            {                max2=max1;                max1=w[num[j]];             }            else                 if(w[num[j]]>max2) max2=w[num[j]];        }        sum=(sum*sum-tmp)%MOD;        ans=(sum+ans)%MOD;        maxn=max(maxn,max1*max2);    }    printf("%d %d",maxn,ans);                   return 0;}
原创粉丝点击