求最小支配集,最小点覆盖,最大独立集
1、概念
最小支配集:选取一个点集,使得剩余的点都与这个集合有边相连,则称这个集合为支配集。如果在点集中去掉一个点而是这个集合不是一个支配集,那么这个集合是一个最小支配集,点集中的点的个数支配数。
最小点覆盖:选取一个点集,使得所有边都与这个集合相连,则称这个集合为点覆盖。也就是说对于任意一条边(u,v),u,v中至少有一个点在集合中。如果在点集中去掉一个点而是这个集合不是一个点覆盖,那么这个集合是一个最小点覆盖,点集中的点的个数为最小点覆盖数。
最大独立集:选取一个点集,使得点集中的点没有边相连,这就是一个独立集。对于一个点集,若添加任意一个点都能使它不是独立集就说这个点集为最大独立集。
贪心解法:
以最小支配集为例,对于树上的最小支配集问题,贪心策略是首先选择一点为根,按照深度优先遍历得到遍历序列,按照所得序列的反向序列的顺序进行贪心,对于一个既不属于支配集也不与支配集中的点相连的点来说,如果他的父节点不属于支配集,将其父节点加入支配集。
这里注意到贪心的策略中贪心的顺序非常重要,按照深度优先遍历得到遍历序列的反向进行贪心,可以保证对于每个点来说,当期子树都被处理过后才轮到该节点的处理,保证了贪心的正确性。
树形动规解法:
最小支配集:
定义状态:
①dp[i][0]:表示点i属于支配集,并且以点i为根的子树都被覆盖了的情况下支配集中所包含的的最少点的个数。
②dp[i][1]:i不属于支配集,且以i为根的子树都被覆盖,且i被其中不少于1个子节点覆盖的情况下支配集中所包含最少点的个数。
③dp[i][2]:i不属于支配集,且以i为根的子树都被覆盖,且i没被子节点覆盖的情况下支配集中所包含最少点的个数。
转移:
dp[u][0]=∑min(dp[v][1],dp[v][2],dp[v][3])+1;
对于第二种状态,如果点i没有子节点,那么dp[i][1]=INF;否则,需要保证它的每个以i的儿子为根的子树都被覆盖,那么要取每个儿子节点的前两种状态的最小值之和,因为此时i点不属于支配集,不能支配其子节点,所以子节点必须已经被支配,与子节点的第三种状态无关。如果当前所选的状态中,每个儿子都没有被选择进入支配集,即在每个儿子的前两种状态中,第一种状态都不是所需点最少的,那么为了满足第二种状态的定义,需要重新选择点i的一个儿子的状态为第一种状态,这时取花费最少的一个点,即取min(dp[u][0]-dp[u][1])的儿子节点u,强制取其第一种状态,其他儿子节点都取第二种状态,转移方程为:
if(i没有子节点)dp[i][1]=INF
else dp[u][1]=Σmin(dp[v][0],dp[v][1])+inc
其中对于inc有:
if(上面式子中的Σmin(dp[v][0],dp[v][1])中包含某个dp[v][0])inc=0;
else inc=min(dp[v][0]-dp[u][1])。
dp[u][2]=Σdp[v][1];
最小点覆盖:
①dp[i][0]:表示点i属于点覆盖,并且以点i为根的子树中所连接的边都被覆盖的情况下点覆盖集中所包含最少点的个数。
②dp[i][1]:表示点i不属于点覆盖,并且以点i为根的子树中所连接的边都被覆盖的情况下点覆盖集中所包含最少点的个数。
dp[i][0]=∑min(dp[u][1],dp[u][0])+1;
dp[i][1]=Σdp[u][0];
最大独立集:
①dp[i][0]:表示点i属于独立集的情况下,最大独立集中点的个数。
②dp[i][1]:表示点i不属于独立集的情况下,最大独立集中点的个数。
dp[i][0]=∑dp[u][1]+1;
dp[i][1]=Σmax(dp[u][0],dp[u][1]);
dp[i][1]=Σmax(dp[u][0],dp[u][1])