算法 {非二分图求最小点覆盖集, 通过拆点 将其转换为二分图}
@LOC_1
非二分图求最小点覆盖集, 通过拆点 将其转换为二分图
定义
#前言#: 由于最小点覆盖集, 可以认为是 权值均为1的最小权点覆盖集, 因此以下统一针对最小权点覆盖集;
给定图G;
@IF(G为无向图): 你需要将他的每条边a-b
, 转换为一条有向边a->b 或 a<-b
, 于是得到了一个有向图GG; (在点覆盖问题中 这两个图是等价的, 因为点覆盖问题不在乎边的方向), 拿这个有向图GG 再进行以下的处理;
对于有向图G, 如果G是满足{传递性 + 反对称性}, 你要求G的点覆盖集, 可以通过拆点 将G转换为二分图GG, 则GG的最小权点覆盖集 可以等效为 G的最小权点覆盖集;
拆点: 比如G的点集为{a,b,c}
, 则G拆点后的图GG的点集为{a,a1,b1,c,c1}
(每个点复制一份), 对于G中的任意边x->y
其对应GG中的边为x->y1
;
最终GG的最小权点覆盖集 一定不会有重复点(即a,a1
不会同时选择), 因此比如GG的最小权点覆盖集是{a,b1,d1}
那么就对应G的最小权点覆盖集为{a,b,d}
;
.
证明: @LINK: @LOC_0
;
举几个例子:
G: a->b->c, 当然隐含了a->c
, GG的最小点覆盖集 可以是{a,c1}
说明G的最小点覆盖集为{a,c}
;
G: a->a
, 则GG的最小点覆盖大小可以是{a1}
对应G的{a}
;
G: a->c, b->c, a->a
, 则GG的最小点覆盖可以是{a,c1}
对应G的{a,c}
;
G: a->c, b->c, c->d, c->e (注意隐含了a->d,a->e...这些边)
, 则GG的最小点覆盖可以为{c1,d1,e1}
对应G的{c,d,e}
;
性质
拆点: G图的x 拆解为 GG图的x1,x2
, 那么就说明 x
与x1,x2
他们是等价的, 也就是 x对应x1,x2
同时x1,x2
对应x
, 比如 选择x1
就说明了是选择了x
选择了x1,x2
也说明是选择了x
;
@DELI;
这个图, 即满足传递性 + 反对称, 他一定是DAG (但也要看你DAG的定义 因为这个图可以有自反性);
但反之不然, 因为DAG可以不满足传递性, 比如a->b->c
是DAG 但不满足传递性 没有a->c
边;
总之 还是要看定义;
@DELI;
@MARK: @LOC_0
;
证明: GG的最小权点覆盖集 将点还原后(即将x1
变成x
) 就是G的最小权点覆盖集;
{
你只要证明了: GG的最小权点覆盖集里 没有重复点(即a,a1
不会同时存在), 那么就证明出来了; 因为覆盖了GG里的所有边 就等于是覆盖了G里的所有边 (G和GG的边 是对应的);
令PRE(x): G中所有可以到达x的点(且非自身x) (即形如?->x的点)
, 令NEX(x): G中所有x可以到达的点(且非自身x) (即形如x->?的点)
; (由于反对称性 PRE(x),NEX(x)
的交集 一定为空), 令Gm: G的最小权点覆盖, GGm: GG的最小权点覆盖
;
#性质#: 对于任意点x
如果没有出现在Gm
里面, 那么PRE(x), SUF(x)
里的所有点 一定出现在Gm
里面; (否则的话 假如y是PRE/SUF(x)里的点
因为有x-y
这条边 而你x,y
都没有选);
.
而且, PRE(x)
会出现在GGm
里(否则的话 ?-x1
这条边无法覆盖) SUF(x)的拆点 (a的拆点为a1)
会出现在GGm
里(否则的话 x-?
这条边无法覆盖);
反证法: 假如x,x1
同时出现在GGm
里 (也说明x
出现在Gm
里);
.
@IF( PRE(x)
里的所有点 都出现在Gm
里面): 你不需要再选择x1
, 因为GGm
里所有?-x1
的边 已经覆盖了;
.
@ELSE: 设y
是PRE(x)
的点 且没有出现在Gm
里, 根据上面的性质 SUF(y)
一定出现在Gm
里, 由于传递性 所以SUF(x)是SUF(x)的子集
, 因此SUF(x)的拆点
一定出现在GGm
里, 即GGm
里所有x-?
的边 已经覆盖了, 因此不需要再选x
;
}
@DELI;
令G1是G的DAG图 (即去掉间接关系 比如G: a->b->c, a->c
那么a->c
为间接关系);
对于G1的任意一条路径, 其上最多只有一个点 不选择(即不出现在G的点覆盖里); 因为如果有两个a,b
由于G里有a->b
他俩肯定至少选择1个;
代码
G: 有向图, 满足{传递性+反对称性};
GG: 答案二分图;
N: G.点数;
设置`GG.点数` = 2*N;
for( [a,b] : G的有向边){
GG.add_edge( a, b+N); // 拆点;
}
则`GG`的最小权点覆盖集 (通过点还原 即a+N->a) 等价于 于`G`的最小权点覆盖集;
错误
#错误#: 对于满足传递性的G: a->c, b->c, c->d, c->e
, 这个图 你很容易以为 他的最小点覆盖是{c}
, 这是错误的! 别忘了他是符合传递性的, 即还有a->d, a->e, b->d, b->e
这些边, 你只选择c
是无法覆盖他们的; 他的最小点覆盖是{a,b,c} 或 {c,d,e}
总之大小为3;
@DELI;
如果G不满足传递性, 这个算法是失效的;
比如 G: a->b->c (注意没有a->c)
, 那么GG的最小点覆盖集是{a,b}
而G的最小点覆盖集是{b}
他俩不是对应的;
如果G不满足反对称性, 这个算法是失效的;
比如G: a<->b
, GG的最小点覆盖集为2 (a,b)
, 而G的最小点覆盖集是1 (a)
;
应用
@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=139181665
;
求图G的最大权独立集 (G满足:传递性,非对称性)