我们从例题入手来考虑仙人掌上DP的一般规律叭.
Ex 1.仙人掌上的单源最短路问题
联想树上最短路,由于路径的唯一性可以直接做一遍O(n)的搜索.但是仙人掌上显然不具备路径的唯一性这种性质.
那么我们是否需要像对待一般的无向连通图一样使用最短路算法呢?
其实并不需要.
首先一遍DFS处理出仙人掌的结构关系.
然后我们从起点开始DP,假设当前DP到节点为x,那么枚举x的每一个儿子.如果该儿子节点是一个普通节点,那么我们直接可以得到起点到这个节点的距离.如果该儿子节点是个环,则枚举环上每一个节点v,求出v到起点距离,再从v开始DP.
同样是一个O(n)的DP.比起无脑跑最短路优越到不知道哪里去了!
Ex 2.求仙人掌的直径
对于有边权和无边权的情况我们一起处理.(无边权当成边权为1)
依然先考虑树的情况.对于树的直径,我们可以使用树形DP,对每个节点求出其深度和以其为根的子树的最大深度,然后每个节点不同儿子的最大深度+次大深度即为答案.
那么仙人掌也是类似的.
首先还是一次DFS处理出仙人掌的结构.
先提出一个子仙人掌的概念,子仙人掌x为删掉节点x到根的所有简单路径上的边后x所在的连通块.
在处理出仙人掌结构之后,我们对每个节点处理出其子仙人掌的最大深度.
对于一个节点,依然可以使用不同儿子的最大深度+次大深度来更新答案.
对于一个环,可以用环上每对节点的最大深度加上这对节点之间的最短路长度来更新答案.
此时我们有两个方法来解决:
1.枚举环上的一个节点,那么如果存在一个节点与当前节点的最短路是从当前节点出发顺时针走,这两个节点一定对应着环上的一个区间.而且不难发现,如果我们当前枚举的节点顺时针移动,这个区间的终点也会同样顺时针移动.处理这种两个端点都单调移动的RMQ问题,可以用单调队列来维护.
2.我们从环的父亲开始,按向下走哪边比较近,把环分成两个部分.可以发现,这两部分内部点对的最短路一定在内部.因此对于每个结点,它在另一部分最短路是顺时针走的一定是一个前缀,最短路是逆时针走的是一个后缀,直接处理前缀max和后缀max即可。
根据这两个例题我们可以看出,除了要DFS处理仙人掌结构是一定的以外,仙人掌上非环点的DP其实和树上DP是基本一样的,在处理仙人掌DP时候比树上DP多的就是怎样处理环上的点.
通常仙人掌上的DP都与距离有关,因此我们可以从上面两个例题中获取灵感来推广到更多问题.
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/creationaugust/article/details/48022291