树形DP水题系列:FAR-FarmCraft [POI2014][luogu P3574]

Posted dah1314

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树形DP水题系列:FAR-FarmCraft [POI2014][luogu P3574]相关的知识,希望对你有一定的参考价值。

题目

大意:

边权为1 使遍历树时到每个节点的时间加上点权的最大值最小 求这个最小的最大值

思路:

最优化问题 一眼树形DP

考虑状态设立 先直接以答案为状态 dp[u] 为遍历完以u为根的子树的答案

再考虑状态转移 dp[u]=MAX(dp[to]+1,siz+dp[to]);siz为枚举子树到以to为节点的子树时之前已遍历的总时间

很明显这个转移过来的dp值的最优化依赖于子树遍历的顺序 所以我们需要找到一种最优的子树遍历顺序来使每个子树得到最优的dp值来更新

我们通过观察可以发现 交换任意两个相邻的子树在遍历时的顺序不会对它们之前的子树和之后的子树造成影响 所以我们考虑贪心 如果只有两个子树 a和b 遍历完子树a,b的时间分别为 siz[a],siz[b],dp值分别为dp[a],dp[b];

将 a优先遍历得到的dp值为MAX(dp[a]+1,siz[a]+dp[b]+3);

将 b优先遍历得到的dp值为MAX(dp[b]+1,siz[b]+dp[a]+3);

注意到取MAX时有一个值不被顺序影响 故只需要将后面的值最优化即可 

我们假设a更优 则 siz[a]+dp[b]+3<siz[b]+dp[a]+3即siz[a]-dp[a]<siz[b]-dp[b]

将子树排序后转移即可

时间复杂度粗略估计(nlogn)

代码如下

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 #define MAXX 500005
 5 #define MAX(a,b) (a>b?a:b)
 6 #define r(x) x=read()
 7 using namespace std;
 8 typedef long long ll;
 9 int h[MAXX],cnt,u,to;
10 int top,n;
11 ll dp[MAXX],w[MAXX],siz[MAXX];
12 struct node{ ll a,b;}nod[MAXX];
13 struct edge{int to,nex;}e[MAXX<<1];
14 void add(int u,int to)
15 {
16   cnt++;
17   e[cnt]=(edge){to,h[u]};
18   h[u]=cnt;
19 }
20 bool cmp(node a,node b){return a.b-a.a<b.b-b.a;}
21 void dfs(int now,int fa)
22 {
23   if(now!=1) {dp[now]=w[now];}
24   for(int i=h[now];i;i=e[i].nex)
25   {
26     if(e[i].to==fa) continue;
27     dfs(e[i].to,now);
28   }
29   for(int i=h[now];i;i=e[i].nex)
30   {
31     if(e[i].to==fa) continue;
32     nod[++top]=(node){dp[e[i].to],siz[e[i].to]};
33   }
34   sort(nod+1,nod+top+1,cmp);
35   for(int i=1;i<=top;++i)
36   {
37     dp[now]=MAX(dp[now],siz[now]+1+nod[i].a);
38     siz[now]+=nod[i].b+2;
39   }
40   if(now==1) dp[now]=MAX(dp[now],siz[now]+w[now]);
41   top=0;
42 }
43 ll read()
44 {
45   ll w=0,ff=1;char ch=0;
46   while(ch<0||ch>9){if(ch==-)ff=-1;ch=getchar();}
47   while(ch>=0&&ch<=9){w=w*10+ch-0;ch=getchar();}
48   return w*ff;
49 }
50 int main()
51 {
52   r(n);
53   for(int i=1;i<=n;++i)
54     r(w[i]);
55   for(int i=1;i<n;++i)
56     r(u),r(to),add(u,to),add(to,u);
57   dfs(1,0);
58   printf("%lld",dp[1]);
59   return 0;
60 }

 

以上是关于树形DP水题系列:FAR-FarmCraft [POI2014][luogu P3574]的主要内容,如果未能解决你的问题,请参考以下文章

ZJOI/Lnsyoj158/Luogu1131时态同步(树形DP水题)做题报告

洛谷P1352 没有上司的舞会(树形DP水题)

2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何

几个树形dp

bzoj2152 聪聪可可 (树形dp)

今日份水题2018.11.2