算法 {二分图}

算法 {二分图}

二分图

算法

非二分图求点覆盖集, 通过拆点 将其转换为二分图

@LINK: https://editor.csdn.net/md/?not_checkout=1&articleId=139158366;

笔记

#二分图#

#定义#

二分图Bipartite Graph;

#前言#: 点集 L , R L, R L,R; 无向边集 E E E;
#条件#: 任意E中的无向边 都形如 ( l i , r j ) (l_i, r_j) (li,rj)的形式(即两个端点 各属于 L , R L,R L,R);
#结论#: 无向图 ( L ∪ R , E ) (L \cup R, E) (LR,E)为二分图;

#等价描述#: 二分图中的所有点 可以分为2类: L , R L,R L,R, 任意无向边的两个端点 一定横跨 L , R L,R L,R;

#相关定义#

A Match (匹配) is a set of edges { ( l 1 , r 1 ) , ( l 2 , r 2 ) , . . . } \{ (l1, r1), (l2,r2),... \} {(l1,r1),(l2,r2),...} such that l i ≠ l j li \neq lj li=lj and r i ≠ r j ri \neq rj ri=rj.

Given a match { ( l 1 , r 1 ) , . . . } \{ (l1, r1), ... \} {(l1,r1),...}, a point a a a is called Matched-Point (匹配点) if a = l i a = li a=li or a = r j a = rj a=rj; otherwise, it is called Unmatched-Point (非匹配点);

--

A Point-Coverage (点覆盖) S S S is a set of points which involves all edges; (i.e., for any edge a 1 − a 2 a1-a2 a1a2, at least one point a i ∈ S ai \in S aiS)

The Minimum Point Coverage (最小点覆盖) is a Point-Coverage with the minimal ∣ S ∣ |S| S;
__. (it usually occurs in the context of Bipartite-Graph)

--

A Independent-Set (独立集) S S S is a set of points such that ( a − b ) ∉ E , ∀ a , b ∈ S (a-b) \notin E, \quad \forall a,b \in S (ab)/E,a,bS.

The Maximum Independent Set (最大独立集) is a Independent-Set with the maximal ∣ S ∣ |S| S;

算法

二分图的存储

假如题意是: 左集合所有点为[1, ..., NL], 右集合所有点为[1, ..., NR], 然后(l, r)表示一条无向边;
#算法#:

G.Initialze( NL + NR);
for( `(l,r)` : 所有边){
	-- l, -- r, r += NL;
	G.Add_edge( l, r), G.Add_edge( r, l);
}

即左集合所有点是[0, NL), 右集合所有点是[NL, NL+NR);

染色法判定二分图

namespace ___Check_BipariteGraph{
vector<int> Flag; // 所有點都染色為`0/1`;

bool Work( const ___Graph & _unDiG){
//< 確保`_unDiG`是*無向圖*;  如果是*二分圖* 則返回值為`true`;
    Flag.resize( _unDiG.PointsCount);  memset( Flag.data(), -1, sizeof(Flag[0]) * Flag.size());

    function<bool(int,int)> Dfs = [&](int _cur, int _flag){
        Flag[ _cur] = _flag;
        for( int nex, e = _unDiG.Head[ _cur]; ~e; e = _unDiG.Next[ e]){
            nex = _unDiG.Vertex[ e];
            if( Flag[ nex]==-1 && false==Dfs( nex, _flag^1)){ return false;}
            if( Flag[ nex] == _flag){ return false;}
        }
        return true;
    };
    for( int i = 0; i < _unDiG.PointsCount; ++i){
        if( Flag[ i]==-1 && false==Dfs( i, 0)){ return false;}
    }
    return true;
}
} // namespace ___Check_BipariteGraph

@DELI;

点覆盖

+ A Point-Coverage S S S, its complementary-set V − S V - S VS is always be a Independent-Set;
. If not, then there is a contradiction: ∃ ( a − b ) ∈ E , a ∈ ( V − S ) ∧ b ∈ ( V − S ) → ∃ ( a − b ) ∈ E , a ∉ S ∧ b ∉ S → S  is not a Point-Coverage \exist (a-b) \in E,a \in (V-S) \land b \in (V-S) \to \exist (a-b) \in E,a \notin S \land b \notin S \to S \text{ is not a Point-Coverage} (ab)E,a(VS)b(VS)(ab)E,a/Sb/SS is not a Point-Coverage
. As a consequence, the complementary-set V − S V-S VS of a Minimum-Point-Coverage S S S, is always be a Maximum-Independent-Set;

在二分图中

let m m m be the maximal-match, cuz these m m m edges are disjoint, ∣ S ∣ |S| S must ≥ m \geq m m.
Conclusion: ∣ S ∣ = m |S| = m S=m where S S S is the Minimum-Point-Coverage; and the process for constructing S S S showed below:

ASSUME( `(l1-r1),...,(ln-rn)` are the Maximum-Matches); //< i.e., `l1,...,ln; r1,...,rn` are all Matched-Points;
ASSUME( `ll1,...,llm; rr1,...,rrk` are all Unmatched-Points);
vector ans := the Minimum-Point-Coverage;
set lef := see below;
for( l : {ll1,...,llm}){
	for( r : the adjacent-points of `l`){
		ASSERT( `r` is a Matched-Point);
		ans.push_back( r);
		lef.insert( $(the corresponding Left-Point of `r` in the Maximum-Matchs));
	}
}
for( l : {l1,...,ln}){
	if( l \in lef){
		continue;
	}
	ans.push_back( l);
}
ASSERT( ans.size() == n);

例题

+ link

独立集

+ A Independent-Set S S S, its complementary-set V − S V - S VS is always be a Point-Coverage;
. If not, then there is a contradiction: ∃ ( a − b ) ∈ E , a ∉ ( V − S ) ∧ b ∉ ( V − S ) → ∃ ( a − b ) ∈ E , a ∈ S ∧ b ∈ S → S  is not a Independent-Set \exist (a-b) \in E,a \notin (V-S) \land b \notin (V-S) \to \exist (a-b) \in E,a \in S \land b \in S \to S \text{ is not a Independent-Set} (ab)E,a/(VS)b/(VS)(ab)E,aSbSS is not a Independent-Set
. As a consequence, the complementary-set V − S V-S VS of a Maximum-Independent-Set S S S, is always be a Minimum-Point-Coverage;
+ ∀ a ∈ S \forall a \in S aS, a a a may have a adjacent-edge ( a − b ) (a-b) (ab) ( b b b must ∉ S \notin S /S);
. ∀ a , b ∈ S \forall a,b \in S a,bS, although there is no edge (not path) between them, they maybe accessible by a path, e.g., a path a − c − b a-c-b acb where c ∉ S c \notin S c/S is possible;

二分图中

Let the Bipartite ( L , R , E ) (L, R, E) (L,R,E), m m m be its maximal-match; for the theorem of Minimum-Point-Coverage, we have m = ∣ S ∣ m = |S| m=S where S S S is the Minimum-Point-Coverage; therefore, we have ∣ L ∣ + ∣ R ∣ − m |L| +|R| - m L+Rm is the size of Maximum-Independent-Set; (that is, once you got the Minimum-Point-Coverage, its complementary-set is the answer)

例题

+ link

延伸阅读

+ DAG的(最小路径点覆盖) link

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值