标签:
如果两两求,那么我们构造一个星形的图,这样的点对就接近n^2对,那么复杂度太高。
那么利用点i,周围的点a,b,c ,如果a,b,c在i的周围那么a,b,c相互之间的距离一定是2。那么他们会产生的值有ab+ac+ba+bc+ca+cb=(a+b+c)^2-a^2-b^2-c^2
故我们可以利用这种方法求出两两之间的和,至于最大值,直接选取a,b,c中的最大值和次大值来产生最大值。下面贴出代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int tov[400005],head[400005],next[400005]; int n,w[200005],a,b,p[200005]; int tot=0; void add(int x,int y) { tot++; tov[tot]=y; next[tot]=head[x]; head[x]=tot; } int main() { freopen("link.in","r",stdin); freopen("link.out","w",stdout); cin>>n; for(int i=1;i<=n;i++)head[i]=-1; for(int i=1;i<=n-1;i++) { scanf("%d%d",&a,&b); add(a,b); add(b,a); } long long ans=0,max=0; for(int i=1;i<=n;i++) scanf("%d",&w[i]); for(int i=1;i<=n;i++) { int cnt=0; long long sum1=0; int max1=0,max2=0; for(int j=head[i];j!=-1;j=next[j]) { p[++cnt]=w[tov[j]]; sum1=(sum1+p[cnt])%10007; ans=(ans-p[cnt]*p[cnt]+10007)%10007; if(p[cnt]>max1)max2=max1,max1=p[cnt]; else if(p[cnt]>max2) max2=p[cnt]; } if(cnt>0) ans=(ans+sum1*sum1)%10007; if(ans<0)ans+=10007; if(max1*max2>max)max=max1*max2; } cout<<max<<‘ ‘<<ans; return 0; }
清清正正射命丸文是也~
标签:
原文地址:http://www.cnblogs.com/Ayateriteri/p/5689785.html