1. 程式人生 > >luogu1351 [NOIp2014]聯合權值 (dfs)

luogu1351 [NOIp2014]聯合權值 (dfs)

\n clr tdi ret space get amp color har

有兩種情況:一個點到它的父親的父親(要算兩次)、一個點的子節點之間互相到達

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=2e5+10,mod=10007;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1
; 10 while(c<0||c>9){if(c==-) neg=-1;c=getchar();} 11 while(c>=0&&c<=9) x=x*10+c-0,c=getchar(); 12 return x*neg; 13 } 14 15 int N,v[maxn]; 16 int eg[maxn*2][2],egh[maxn],ect; 17 int fa[maxn],mans,ans; 18 19 inline void adeg(int a,int b){ 20 eg[++ect][0
]=b;eg[ect][1]=egh[a];egh[a]=ect; 21 } 22 23 void dfs(int x){ 24 int mm=0; 25 if(fa[fa[x]]){ 26 mans=max(mans,v[x]*v[fa[fa[x]]]); 27 ans=(ans+v[x]*v[fa[fa[x]]]*2)%mod; 28 } 29 int sum=0; 30 for(int i=egh[x];i;i=eg[i][1]){ 31 int b=eg[i][0];if(b==fa[x]) continue
; 32 sum=(sum+v[b])%mod; 33 mans=max(mans,mm*v[b]); 34 mm=max(mm,v[b]); 35 fa[b]=x;dfs(b); 36 } 37 for(int i=egh[x];i;i=eg[i][1]){ 38 int b=eg[i][0];if(b==fa[x]) continue; 39 ans=(ans+v[b]*(sum-v[b]))%mod; 40 } 41 } 42 43 int main(){ 44 //freopen(".in","r",stdin); 45 int i,j,k; 46 N=rd(); 47 for(i=1;i<N;i++){ 48 int a=rd(),b=rd(); 49 adeg(a,b);adeg(b,a); 50 } 51 for(i=1;i<=N;i++) v[i]=rd(); 52 dfs(1); 53 printf("%d %d\n",mans,(ans%mod+mod)%mod); 54 return 0; 55 }

luogu1351 [NOIp2014]聯合權值 (dfs)