1. 程式人生 > 其它 >聯合權值

聯合權值

聯合權值NOIP2014

#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;
}