/**********************************************題目地址:http://acm.whu.edu.cn/land/problem/detail?problem_id=1461題目大意:定義的一個求ch值的函數(見下面注釋部分);即求樹中根結點的ch值的方法,要你想辦法幫他實現這個程式;演算法思想:先一條鏈的情況:設第一個點的值是a,第二個是b,第三個是c...那麼有:ch[1]=ach[2]=a+bch[3]=max(2a+c,a+b+c)ch[4]=max(3a+d,2a+2b+d,2a+c+d,a+b+c+d)ch[5]=max(4a,3a+3b,4a+c,2a+2b+2c,value[4])+e可以發現4a+c>4a,可得結論:一個點的ch值最多從不超過3層的地方轉移而來;記錄每個節點最下三層最大的ch值,然後當前節點從這三個值中取最大的轉移即可;這是官方的解題報告,我是有點沒怎麼看懂,求大神來一發;***********************************************/#include<iostream>#include<cstring>#include<cmath>#include<cstdio>#include<cstdlib>#include<vector>#include<algorithm>using namespace std;const int N=11111;typedef long long LL;int n;LL ch[N][4];LL value[N];vector<int>v[11000];/*LL ch[N],value[N],depth[N];int cal(int v){ ch[v]=value[v]; if (v is leaf) return value[v]; ch[v]=0; for( all u which is descendant of v ) ch[v]=max(ch[v],cal(u)*(depth[u]–depth[v])+value[v]) return ch[v];}*/void dfs(int u,int father){ if(v[u].size()==1&&v[u][0]==father) { ch[u][0]=value[u]; ch[u][1]=ch[u][2]=0; return; } for(int i=0; i<v[u].size(); i++) { if (v[u][i]==father) continue; dfs(v[u][i],u); int j=v[u][i]; ch[u][0]=max(ch[u][0],max(ch[j][0],max(ch[j][1]*2,ch[j][2]*3))+value[u]); ch[u][1]=max(ch[u][1],ch[j][0]); ch[u][2]=max(ch[u][2],ch[j][1]); }}int main(){ //freopen("C:\\Users\\Administrator\\Desktop\\kd.txt","r",stdin); int tcase; scanf("%d",&tcase); int t=0; while(tcase--) { memset(ch,0,sizeof(ch)); scanf("%d",&n); for(int i=1; i<=n; i++) { v[i].clear(); scanf("%lld",&value[i]); } int x,y; for(int i=1; i<n; i++) { scanf("%d%d",&x,&y); v[x].push_back(y); v[y].push_back(x); } dfs(1,0); t++; printf("Case %d: %lld\n",t,ch[1][0]); } return 0;}