Codeforces Beta Round #69 (Div. 2 Only) E树型DP 一树,每个结点有虫子,一次只能吃一只,不能停留,问从根结点出发再回到根结点最多能吃多少只虫子

来源:互联网 发布:qq大数据 编辑:程序博客网 时间:2024/04/28 17:30
 
/*题意:一树,每个结点有虫子,一次只能吃一只,不能停留,问从根结点出发再回到根结点最多能吃多少只虫子思想:记录从某个结点出发再回到该结点最多能吃的虫子,然后      由将子结点按能吃的虫子数排序,选择。注意可能多次下去。*/#include <iostream>#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;const int maxn=110000;const int maxm=210000;struct edge{int u,v,next;}e[maxm];int num,edgeNum,p[maxn],first[maxn];__int64 a[maxn];void Addedge(int u,int v){e[edgeNum].u=u,e[edgeNum].v=v,e[edgeNum].next=first[u],first[u]=edgeNum++;e[edgeNum].u=v,e[edgeNum].v=u,e[edgeNum].next=first[v],first[v]=edgeNum++;}__int64 DFS(int t,int f,int &left){int i,j=num,k,ii,jj=0;__int64 sum=1;//从根结点到此结点要吃一个for(k=first[t];k!=-1;k=e[k].next){if(e[k].v==f) continue;a[num++]=DFS(e[k].v,t,ii);jj+=ii;//以e[k].v为根结点时,它还剩多少虫子}sort(a+j,a+num);for(i=num-1;i>num-1-p[t]&&i>=j;i--)sum+=a[i]+1;//下去吃a[i],回来此结点再吃一个if(p[t]>num-j)//还要再下去{if(p[t]-num+j>=jj){sum+=2*jj;left=p[t]-num+j-jj;}else{sum+=2*(p[t]-num+j);left=0;}}else left=0;num=j;return sum;}int main(){int n,u,v,i,j;while(scanf("%d",&n)!=EOF){for(i=1;i<=n;i++){scanf("%d",&p[i]);p[i]--;}memset(first,-1,sizeof(first));for(edgeNum=0,i=1;i<n;i++){scanf("%d%d",&u,&v);Addedge(u,v);}scanf("%d",&u);p[u]++;num=0;printf("%I64d\n",DFS(u,-1,i)-1);}    return 0;}

原创粉丝点击