聯合權值
阿新 • • 發佈:2022-04-04
#include<bits/stdc++.h> #define LOCAL using namespace std; typedef long long int ll; int read(){ int s=0,f=1,c=getchar(); while (c<'0' || c>'9') { if (c=='-') f=-1; c=getchar();} while (c>='0' && c<='9') {s=(s<<3)+(s<<1)+c-'0';c=getchar();} return s*f; } const int maxn=2e5+5; vector<int> g[maxn]; int w[maxn]; bool vis[maxn]; const int mod=10007; int sum=0; int mm=0; /* dfs走一遍,中間記錄上一個點和上上一個點 */ //void dfs(int p,int q){ // int len=(int)g[q].size(); // vector<int> cld; // for (int i=0;i<len;++i){ // int nw=g[q][i]; // if (vis[nw]) continue; // vis[nw]=1; // if (p){ // int tmp=w[nw]*w[p]; // mm=max(mm,tmp); // sum=(sum+tmp)%mod; // } // dfs(q,nw); // } //} //void dfs(int p,int q){ // int len=(int)g[q].size(); // vis[q]=1; // for (int i=0;i<len;++i){ // int nw=g[q][i]; // //for (int j=0;j<i;++j){ ////// if (find(g[nw].begin(),g[nw].end(),g[q][j])!=g[nw].end()) continue; // 必是樹。。。 //// int tmp=w[nw]*w[g[q][j]]; ////// cout<<nw<<" "<<g[q][j]<<endl; //// mm=max(mm,tmp); //// sum=(sum+2*tmp)%mod; //// } // // math is TMD powerful : 2xy=(x+y)^2-(x^2+y^2) // // 感覺沒要dfs了,直接遍歷就可以 // if (vis[nw]) continue; //// vis[nw]=1; // dfs(q,nw); // } //} int main(){ #ifdef LOCAL freopen("input.txt","r",stdin); #endif int n=read(); for (int i=1;i<n;++i){ int u=read(),v=read(); g[u].push_back(v); g[v].push_back(u); } for (int i=1;i<=n;++i) w[i]=read(); // dfs(0,1); for (int i=1;i<=n;++i){ int len=(int)g[i].size(); int m1=0,m2=0,sum1=0,sum2=0; for (int j=0;j<len;++j){ int t=g[i][j]; if (w[t]>=m1){ m2=m1; m1=w[t]; } else if (w[t]>m2) m2=w[t]; sum1=(sum1+w[t])%mod; sum2=(sum2+w[t]*w[t])%mod; } mm=max(mm,m1*m2); sum=(sum+(sum1*sum1%mod+mod-sum2)%mod)%mod;// 雖然(如果不mod的話)sum1>sum2,但是這裡有可能是個負值(在取模運算的時候必須注意負值!!!) } printf("%d %d",mm,sum); return 0; }