题目描述 Description
输入描述 Input Description
输出描述 Output Description
样例输入 Sample Input
样例输出 Sample Output
数据范围及提示 Data Size & Hint
思路:
1、以每一个点为轴,左右两个点算权值
1、以每一个点为轴,左右两个点算权值
2、注意加法结合律(a+b+c)2 = a2 + b2 + c2 + 2ab + 2ac + 2bc
3、取模问题,(a+b)%c ≠ (a%c + b%c)%c,(a + b) % c = (a + b%c)%c
代码:
(注意链式前向星的使用)
#include<cstdio> #include<iostream> using namespace std; const int maxn =400020; struct edge{ int next; int to; int power; }; edge test[maxn]; int head[maxn],cur = 0,n,j[maxn],p[maxn],max1[maxn],max2[maxn],nmax1[maxn],coun[maxn]; long long int vall = 0,vmax = 0,sub =0; int use(int i) { int t=head[i]; int ti,tmp,sum=0,cha2=0; while (t!=-1) { ti=test[t].to; sum=(sum+p[ti]%10007)%10007; cha2+=p[ti]*p[ti]%10007; if (p[ti]>max1[i] ) { max1[i]=p[ti]; nmax1[i]=ti; } t=test[t].next; coun[i]++; } sum=(sum*sum%10007 +10007-cha2%10007)%10007; vall+=sum%10007; return sum; } /*int dfs(int deep,int last,int now){ if(deep == 2){ if(last == now) return 0; int temp; temp = p[now]* p[last]; if(temp > vmax) vmax = temp; return 0; } for(int k=head[now];k>-1;k=test[k].next){ dfs(deep + 1,last,test[k].to); } } */ void dfs(int i) { int ansi=1; if (coun[i]>1) { int t=head[i]; int ti; while (t!=-1) { ti=test[t].to; if (ti!=nmax1[i] ) { if (p[ti]>max2[i] ) max2[i]=p[ti];} t=test[t].next; } } if (vmax<max1[i]*max2[i] ) vmax=max1[i]*max2[i]; } void add(int u,int v,int w){ test[cur].power = w; test[cur].to = v; test[cur].next = head[u]; head[u] = cur++; } int main(){ cin>>n; int u,v,w; for(int i = 0;i < n;i++){ test[i].power = 1; test[i].next = -1; head[i] = -1; j[i] = 1; } int tu,tv; for(int i = 0;i < n-1;i++){ cin>>tu>>tv; tu--; tv--; add(tu,tv,1); add(tv,tu,1); } for(int i = 0;i < n;i++) cin>>p[i]; for(int i = 0;i < n;i++)use(i); for(int i = 0;i < n;i++)dfs(i); cout<<vmax<<" "<<vall % 10007<<endl; return 0; }