题目描述
输入输出格式
输入格式:
输出格式:
一行,包含一个整数,代表题目中所说的最小时间。
输入输出样例
样例输入

1 6 2 1 8 9 6 3 2 3 1 3 4 2 3 5 3 4 6 4 5 7 4 6
样例输出

1 11
提示
分析
我们设f[x]为遍历完以x为根的子树且将这棵子树上所有的电脑都安装完毕最终又回到x的最小安装时间
对于一棵子树,根节点所需要的安装时间自然是它本身的价值
那么各个子节点的价值可以直接拿来用吗?显然是不可以的
因为你从根节点遍历到子节点需要花费时间
所以这时就有遍历优先级的问题了
我们是先遍历安装时间最长的子树吗?这样是不可以的,比如下面这幅图
那我们该怎么办呢,我们可以发现,
代码

1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn=1000005; 8 struct Edge{ 9 int next,to; 10 }e[maxn]; 11 int head[maxn],len; 12 void Ins(int a,int b){ 13 e[++len].to=b;e[len].next=head[a];head[a]=len; 14 } 15 struct Node{ 16 int f,siz; 17 Node(){} 18 Node(int a,int b){f=a,siz=b;} 19 bool operator < (const Node&A)const{ 20 return f-siz<A.f-A.siz; 21 } 22 }; 23 int dp[maxn],g[maxn],val[maxn],que[maxn]; 24 void dfs(int u,int fa){ 25 priority_queue<Node> q; 26 if(u-1)dp[u]=val[u]; 27 for(int i=head[u];i!=-1;i=e[i].next){ 28 int v=e[i].to; 29 if(v==fa)continue; 30 dfs(v,u);q.push(Node(dp[v],g[v])); 31 } 32 while(!q.empty()){ 33 Node now=q.top();q.pop(); 34 dp[u]=max(dp[u],now.f+g[u]+1); 35 g[u]+=now.siz+2; 36 } 37 } 38 int main(){ 39 memset(head,-1,sizeof(head)); 40 int n; 41 scanf("%d",&n); 42 for(int i=1;i<=n;i++) 43 scanf("%d",&val[i]); 44 for(int i=1;i<n;i++){ 45 int a,b; 46 scanf("%d%d",&a,&b); 47 Ins(a,b);Ins(b,a); 48 } 49 dfs(1,0); 50 printf("%d ",max(dp[1],val[1]+g[1])); 51 return 0; 52 }