算法 {染色法判定二分图,点覆盖,独立集}
二分图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)
(L∪R,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 a1−a2, at least one point a i ∈ S ai \in S ai∈S)
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 (a−b)∈/E,∀a,b∈S.
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 Flag; // 所有點都染色為`0/1`;
bool Work( const ___Graph & _unDiG){
//< 確保`_unDiG`是*無向圖*; 如果是*二分圖* 則返回值為`true`;
Flag.resize( _unDiG.PointsCount); memset( Flag.data(), -1, sizeof(Flag[0]) * Flag.size());
function 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
V−S 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}
∃(a−b)∈E,a∈(V−S)∧b∈(V−S)→∃(a−b)∈E,a∈/S∧b∈/S→S is not a Point-Coverage
.
As a consequence, the complementary-set
V
−
S
V-S
V−S 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
V−S 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}
∃(a−b)∈E,a∈/(V−S)∧b∈/(V−S)→∃(a−b)∈E,a∈S∧b∈S→S is not a Independent-Set
.
As a consequence, the complementary-set
V
−
S
V-S
V−S of a Maximum-Independent-Set
S
S
S, is always be a Minimum-Point-Coverage;
+
∀
a
∈
S
\forall a \in S
∀a∈S,
a
a
a may have a adjacent-edge
(
a
−
b
)
(a-b)
(a−b) (
b
b
b must
∉
S
\notin S
∈/S);
.
∀
a
,
b
∈
S
\forall a,b \in S
∀a,b∈S, 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
a−c−b 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∣+∣R∣−m is the size of Maximum-Independent-Set; (that is, once you got the Minimum-Point-Coverage, its complementary-set is the answer)
+
link