已经AK了的就进来看看吧
黑暗爆炸4390 Max Flow
题意: 给定一棵有N个点的树,所有节点的权值都为0。有K次操作,每次指定两个点s,t,将s到t路径上所有点的权值都加一。请输出K次操作完毕后权值最大的那个点的权值。
树上点的差分
1 |
|
POJ3417 Network
题意: 个节点,条旧边连接所有的点,还有m条新的边。问,删一条旧边和新边,将这些点分成两个部分,一共有多少种方案。
题解: 题目保证条旧边连接所有的点,也就是说但看旧边部分,就是一棵树;从这些边中任意删除一条,一定能将这棵树分成两部分。再看m条新边。
假设一条新边建在了u点和v点之间:
- 如果不删除这条新边,单单删除u和v之间的旧边,是不足以将树分成连个部分的。必须要删除这条新边,删除u和v之间的旧边才能将树分成两个部分。
- 除了u和v之间的所有旧边,因为没有新边的干扰,删除任意一条都能将树分成两部分。
假设右两条新边建在了u和v点之间:
- 即使删除了一条新边,也会变成上一种情况,删除u和v之间的旧边不能将树分成两部分
- 除了u和v之间的所有旧边,因为没有新边的干扰,删除任意一条都能将树分成两部分。
变式: 将原有的n-1条边,建成一棵树。所有边权为0。之后m条新边,看作是m次操作,u和v之间的新边,就看作是将u到v之间的所有边的权值都加上1。如此一来:
- 某处u和v之间的边权为0。说明此处只有一条旧边,删除即可将树分成两个部分。另外还可以任意删除m条边。【题目要求删除一条旧边和一条新边】
- 某处u和v之间的边权为1。说明此处右一条旧边和一条新边,需要同时将两条边都删除,才可将树分成两部分。
- 某处u和v之间的边权大于1。说明此处不止一条新边,怎么删除都无济于事;。
树上边权的维护——树上边的差分。
1 |
|
POJ3107 Godfather
求树的重心
1 |
|
HDU2196 Computer
题意: 一棵有根树,求所有节点在树中的最大距离。
树形DP
1 |
|
POJ3140 Contestants Division
题意: 一棵带权树,删除某条边,求两棵子树的最小权值差。
题解: 定义dp[i]表示以i为根节点的子树的权值和。如果u是v的父节点,则有dp[u] = 。如果切断u和v之间的边,权值差则为sum - 2 * dp[v]
树形DP
1 |
|
HDU1520 Anniversary party
题意: 公司宴会,员工之间存在直接的上下级关系,如果两人同时出席宴会会很尴尬,所以直接不允许这样的上下级同时出席。求宴会上能邀请的最大人数。
题解: 员工和直属上司不能同时出席。这题目乍一看就好像二分图匹配。啥是二分图匹配?不是今天的重点,自行百度。 直白点问,树形DP怎么做?
定义
dp[i][0]表示不选择员工i能获得的最大人数。
定义dp[i][1]表示选择员工i能获得的最大人数。
那其实状态转移就很明了了【比如u是v的直属上司】
dp[u][0] += max(dp[v][1], dp[son][0]);虽然我不让u出席宴会,但不代表v一定要出席宴会。比较一下v出席和不出席能获得的最大人数,取其中较大值即可。
dp[u][1] += dp[v][0];这个就比较明确了,u想出席,v必须不能在场
树形DP
1 |
|
HDU3586 Information Disturbing
题意: 一棵有边权的树,要求删除一些边,使得根节点1和所有的叶子节点断开联系。要求是:
- 删除的边的权值和必须小于m
- 删除的边权的最大值尽可能小
题解: 两个条件看似是不能统一的,总和必须小于m,但是最大权值又要尽可能小。
举个栗子,如果DFS过程中追求权值和最小,那么将会得到答案6,但这个却不是最小的最大权。
对于这种,就应该去枚举最大权,然后DFS验证是否正确。当然,应该二分枚举。
树形DP + 二分
1 |
|
POJ3162 Walking Race
题意: 一棵n个节点、有边权的树。第天则从点出发,记录下能跑到的最远距离。求一个最大的连续天数,使得其中的最大距离 - 最小距离 < m
题解: 树形DP求解每个点在树上的最远距离,然后线段树维护区间最大值与最小值。
树形DP + 线段树
1 |
|
HDU4126 Genghis Khan the Conqueror
题意: 给定一个带权无向图G,n个点m条边,每条边都有一个权值w。题目保证两个点之间最多只有一条边。接下来有Q次边权的改变,且改变后的权值之后一定比原来的更大。求每次改变边权之后的所有最小生成树的平均值(边权的改变前后不影响。
题解:
- 构造最小生成树: 在没有任何边权改变之前,求出最原始的最小生成树,记录这棵树的权值和
ans。 - 边权替换: 再次强调,每次边权的改变,是独立操作、前后互补影响的。明确之后再对改变的边权进行分类讨论:
- 边在树上: 这次改变的边在最原始的最小生成树上,并且题目保证改变的边权一定比原来的大,所以一定会影响最小生成树的结果。办法是在原始的最小生成树上,断开这条改变的边,从分开的两棵树,找到一条连接两棵树的最小边。则
新的生成树的权值和 = ans - 改变的边(原来的值) + 连接两棵树的最小边 - 边不在树上: 如果改变的边不在原始的最小生成树上,那其实是不会影响结果的,改变后的最小生成树还是原来的生成树,那么
权值和 = ans
- 边在树上: 这次改变的边在最原始的最小生成树上,并且题目保证改变的边权一定比原来的大,所以一定会影响最小生成树的结果。办法是在原始的最小生成树上,断开这条改变的边,从分开的两棵树,找到一条连接两棵树的最小边。则
- 连接两棵子树的最小边: 既然我们决定将最小生成树上那条改变的边断开,那么这棵树就会分成两棵子树,但是要如何找到连接两棵子树的最小边?
- 树形DP: 定义状态
dp[u][v]表示点u在的这棵子树到点v在的这颗子树的最小边权。(树形DP这块太难解释了,看代码吧)
- 树形DP: 定义状态
最小生成树 + 树形DP
1 |
|