UVa 10795 A Different Task

题意

可以参考LRJ大礼包白书第一章例题11

和汉诺塔游戏一样的规则,区别是这个问题会给出多达60个圆盘每一个最开始在哪根柱子上,要你求出从这个局势开始到终盘(00n)最少要移动多少次。

思路

大概是个。。。构造题?

思路比较复杂,而且还涉及传统汉诺塔问题的结论(把一根有k个盘子的堆移到一个空柱子上,需要((2^k)-1)步)。

具体的思路可以参考白书P27.

代码

POJ 2114 Boatherds

题意

给出一棵树,树边带有边权,问你能不能找出一条路径使得路径边权之和正好等于给出的k值。

思路

和这个题非常像,只不过题意从计算有多少点对之间距离小于k换成了判断有没有一条路径等于k。但实际上可以用一套思路解决。

代码

 

POJ 1987 Distance Statistics

题意

给出一棵树,和树上两点之间的边权大小,要你快速回答出树上有多少不同的点对使的这对点之间的距离至多为k。

思路

典型的点分治问题。

当考虑一棵有根树中有多少点对的距离小于等于k时,可以求出所有节点到根部的距离,然后使用二分,或者尺取的方法得到有多少对点之间的距离小于等于k。但是在上面的计算过程中我们想要求的是经过根部的符合要求的点对数量,但实际上多算入了一些并不符合要求的点,同时也漏掉了不经过根部的符合条件的点对。

所以我们可以这样看:一棵树的符合条件点对数=上面所述方法找出的点对数-各个子树中两点间距小于等于(k-2e)的点对数目(e是根部到孩子的树边的边权)+各个子树符合条件的点对数

上面的式子是递归的,这是一个树分治(点分治)策略。

在实现树分治的时候,一定要注意只有配合了重心的点分治才能达到O(nlogn)的复杂度,否则会面临特殊情况(比如链)退化到O(n^2).

代码

 

 

POJ 3107 Godfather

题意

变相考察树的重心。

思路

请参考这个题和/或这个题

代码

 

POJ 2378 Tree Cutting

题意

变相考察求树的重心。

思路

和这个题一致

代码

 

POJ 1655 Balancing Act

题意

求树的重心。

思路

树的重心的定义是:选树中某个点i当作树的根,所有子树中最大的那棵的大小是Si,整棵树中能令Si最小的那个点,就是树的重心。

求重心是作为树分治的一个环节出现的,只有保证了每一次点分治的位置都是重心才能保证树分治的复杂度为O(nlogn)。

求重心的想法是树dp,对于每个节点都要存储他所有孩子对应的子树中最大子树的大小,还要存储他的父亲是谁。求好了这些数据之后,按着定义,就可以知道谁是重心了。

代码

 

Codeforces 573C Bear and Drawing

题意

你要在两条平行直线之间画一棵有n个节点的树,树必须是可平面的(意思就是不能有两条链发生相交的情况)。给出你若干个连边(他们已经组成一棵树),问你是否可能画出符合要求的树。

思路

通过小数据找规律,可以要想把一棵树的安排在两条平行直线上,这棵树需要满足以下几个条件:

  • 首先我们在树上找到一条主链
  • 凡是在主链上的点,它的度数没有限制
  • 与主链直接相连的点,它的度数最大为3
  • 剩下的点,度数最大为2

知道了这些,接下来就是实现的问题了。这里有一种很聪明的实现方法。

  • 首先,统计所有节点的度数。
  • 在每一个叶子节点都发动一次DFS,在DFS过程中若遇到的一切度数小于等于2的点,进入,并做删除标记,否则返回。这一步的目的是清除掉所有叶子节点所属的链(不能直接修改度数,否则会导致删掉整棵树)。
  • 重新统计每个节点的度数,因为刚才只是做标记,没有改变度数。
  • 接下来对于所有曾经为3度现在为1度的点打删除标记,这种点是与主链直接相连的点。
  • 重新统计每个点的度数。
  • 现在每个节点的度数都理应小于3了,因为我们刚才去掉了叶子节点所在的链,如果这棵树正确,一定会删到主链上。接下来又去掉了曾经3度删完1度的节点,这相当于完全去掉了支链。这个时候整棵树理应只剩一条链了,不可能再有度数大于2的节点了。

如果理解有困难,不妨尝试画图帮助理解。

代码

 

UVa 11384 Help is needed for Dexter

题意

请参考LRJ白书第一章例题10

思路

试验小数据,找规律。

代码

 

UVa 11464 Even Parity

题意

请参考LRJ白书第一章例题7.

思路

大概是个带有机智成分的枚举。

为什么这么说,因为这道题的关键思路点就是发现只要知道第一行,就可以构造出整个数表,这样我们只要枚举第一行就可以解决问题,复杂度直接降低了一次幂。

代码

 

 

UVA 10881 Piotr's Ants

题意

请参考LRJ白书第一章例题5

思路

两个蚂蚁相遇会马上调换方向,从视觉上看其实相当于擦身而过(虽然两只蚂蚁的身份并没有交换)。就像在物理中,两个质量相等的小球发生完全弹性碰撞,交换速度。这里是本题第一个思路点。

无论在任何时候,第i只蚂蚁永远是第i只蚂蚁,因为上面也说了,只是视觉上的擦身,实际上蚂蚁又各自回去了。这是第二个思路点。在这个地方还有一个问题,那就是可能会以为仅仅是位置关系保持原来的顺序,其实方向关系也是保持原来的顺序的,这样就可以解决蚂蚁的最终状态的判定问题。

这样我们就有了解法:首先利用擦身而过的想法,求出最终所有蚂蚁的分布。然后利用标号守恒的想法,把终止状态和起始状态对应。

代码

 

Scroll to top