上一篇好像已经够长了。。。新开一篇
现在做了几道:
12
考虑树DP,我们发现子树走的顺序不同最优值也不同。所以需要安排一个顺序,使得该子树中最晚安装好的点最早安装好。
这就需要国王游戏中考虑相邻节点的类似方法,具体推导可以见claris神犇的题解:
http://hi.baidu.com/clrs97/item/408d0adb61dc4f5d21e25078
1 int n,head[maxn],tot,f[maxn],d[maxn],a[maxn]; 2 struct edge{int go,next;}e[2*maxn]; 3 inline void add(int x,int y) 4 { 5 e[++tot]=(edge){y,head[x]};head[x]=tot; 6 e[++tot]=(edge){x,head[y]};head[y]=tot; 7 } 8 inline bool cmp(int x,int y){return max(f[x],d[x]+2+f[y])<max(f[y],d[y]+2+f[x]);} 9 inline void dfs(int x,int fa) 10 { 11 for4(i,x)if(y!=fa)dfs(y,x),d[x]+=d[y]+2; 12 int m=0,sum=0; 13 for4(i,x)if(y!=fa)a[++m]=y; 14 sort(a+1,a+m+1,cmp); 15 for1(i,m) 16 { 17 f[x]=max(f[x],sum+f[a[i]]+1); 18 sum+=d[a[i]]+2; 19 } 20 } 21 22 int main() 23 24 { 25 26 freopen("input.txt","r",stdin); 27 28 freopen("output.txt","w",stdout); 29 30 n=read(); 31 for1(i,n)f[i]=read(); 32 int ans=f[1]; 33 for1(i,n-1)add(read(),read()); 34 dfs(1,0); 35 ans=max(2*n-2+ans,f[1]); 36 printf("%d\n",ans); 37 38 return 0; 39 40 }