Contents

  • 术语
  • 二分图
    • 旧解释
  • 染色法判定二分图
    • 经验总结
  • 匈牙利算法计算最大匹配
    • 例题
    • 经验总结
  • 点覆盖
    • 在二分图中
    • 例题
  • 独立集
    • 二分图中
    • 例题
  • 延伸阅读

术语

A Bipartite-Graph (二分图) is a undirected-graph whose all points can be divided into two sets: LLL-Set and RRR-Set, all edges a−ba-ba−b such that one of its endpoint belongs to LLL and the another belongs to RRR;
+ For any a∈L,b∈Ra \in L, b \in Ra∈L,b∈R, it always has a≠ba \neq ba=b; (for the definition, all points divided into two kinds.

--

A Match (匹配) is a set of edges {(l1,r1),(l2,r2),...}\{ (l1, r1), (l2,r2),... \}{(l1,r1),(l2,r2),...} such that li≠ljli \neq ljli=lj and ri≠rjri \neq rjri=rj.

Given a match {(l1,r1),...}\{ (l1, r1), ... \}{(l1,r1),...}, a point aaa is called Matched-Point (匹配点) if a=lia = lia=li or a=rja = rja=rj; otherwise, it is called Unmatched-Point (非匹配点);

--

A Point-Coverage (点覆盖) SSS is a set of points which involves all edges; (i.e., for any edge a1−a2a1-a2a1−a2, at least one point ai∈Sai \in Sai∈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 (独立集) SSS 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∣;

二分图

Given a Bipartite-Graph (L,R,E)(L, R, E)(L,R,E) where EEE is undirected, in the algorithm, it would be stored in the form (L,R,E1)(L, R, E1)(L,R,E1) where a undirected-edge ∀(a−b)∈E\forall (a-b) \in E∀(a−b)∈E (let a∈La \in La∈L, if not swap(a,b)) corresponding to a directed-edge (a→b)∈E1(a\to b) \in E1(a→b)∈E1; we call such a graph be Standard-Bipartite-Graph;
+ An edge a→ba\to ba→b in Standard-Bipartite-Graph, corresponds to an Undirected-Edge (a−b)(a-b)(a−b) in the normal Bipartite-Graph; (note that, the Bipartite-Graph is always Undirected (even although for the Standard-Bipartite-Graph), it is just the storage-form in computer which seems like a directed-graph, but in essence, it is undirected.
+ An usual (special) technique for transforming a Bipartite-Graph to a Standard-Bipartite-Graph
. Given you a Bipartite, you don’t need to using Flag-Coloring to transform the Bipartite to be Standard; If the graph is a Grid, and all edges are between two cells; a usual method is to dividing all cells into L,RL,RL,R-Sets in the below way:

0 1 0 1 0
1 0 1 0
0 1 0
1 0
0if( (x + y) & 1){ belongs to one-set}
else{ belongs to anothe-set}

. For instance, if all edges are a−ba-ba−b where let a=(x,y)a=(x,y)a=(x,y) then bbb must be the endpoint in the direction (1,0)(−1,0)(0,1)(0,−1)(1,0) (-1,0) (0,1) (0,-1)(1,0)(−1,0)(0,1)(0,−1); the endpoints of such edges are located in two-sets in the coloring-strategy above;
. Or if the direction is (2,1)(1,2)(−2,1)(−1,2)(2,−1)(1,−2)(−2,−1)(−1,−2)(2,1) (1,2)(-2,1) (-1,2)(2,-1) (1,-2)(-2,-1) (-1,-2)(2,1)(1,2)(−2,1)(−1,2)(2,−1)(1,−2)(−2,−1)(−1,−2), it also satisfies.

旧解释

Bipartite-Graph is a undirected graph with certain properties (not two graphs).

Satisfying:

  • All points can be marked into two flags (let’s call flag A,BA, BA,B), for any edge (a,b)(a,b)(a,b), their flags must be distinct.
    (e.g., 1-2-3-4-1 it can be marked 13:A,24:B13:A, 24:B13:A,24:B or 13:B,24:A13:B, 24:A13:B,24:A. but 1-2-3-1 is not a Bipartite-Graph)

Visually, you can put all points that are marked AAA into a Set-A, and the same process for BBB, then the Graph is absolutely same to the Original-Graph (we just change its appearance)
A:( ...) B: ( ...), then there are no edge within AAA or BBB, alternatively, all edges of GGG are the form of connecting one point of AAA to one point of BBB.
This form is not unique (e.g., for a isolated point, it can belongs to AAA or BBB)


There are some kinds of Sub-Graphs in a undirected graph:

  • A isolated point. (it can marked arbitrarily, so it is a Bipartite)
  • A chain 1-2-3-4-5. (it is also a Bipartite)
  • A loop 1-2-3-...-1
    • With even number of points. 1-2-3-4-1 (it is OK)
    • With odd number of points. 1-2-3-1 (it is NOT)

So, p=(GisBipartite),q=(noodd_loopinG)p = (G \ is \ Bipartite), q = (no \ odd\_loop \ in\ G)p=(G is Bipartite),q=(no odd_loop in G), then we have p→qp \to qp→q, moreover, ¬q→¬p\lnot q \to \lnot p¬q→¬p

This is just a property (the algorithm for checking whether a graph is a Bipartite, will not use this property) , and we don’t know whether q→pq \to pq→p is true.


染色法判定二分图

Given a undirected and unweighted graph, check whether it is a Bipartite-Graph.

The algorithm is based on the Flag-Marking principle as mentioned above.

There are some lemmas that are used in the algorithm:

  • Due to GGG maybe not connected, suppose that GGG has several connected Sub-Graphs G1,G2,G3G1, G2, G3G1,G2,G3.
    G is Bipartite ↔↔↔ G1, G2, G3 are both Bipartite
  • For a connected graph which is a Bipartite, it has two marking schemes (e.g. (abc): A, (de): B or (abc): A, (de): B.

According to these lemmas, we use Flag[]Flag[]Flag[] (-1 is not visited by DFS, 0 is one flag, 1 is another flag) to denote the flag of every point, use DFS to iterate every point in a connected Graph.

void Dfs( int _cur, int _fa, int _flag){Flag[ _cur] = _flag;for( int nex, e = G.Head[ _cur]; ~e; e = G.Next[ e]){nex = G.Vertex[ e];if( Flag[ nex] == -1){Dfs( nex, _cur, _flag ^ 1);}if( Flag[ nex] == _flag){Succ = false;break;}}
}int main(){Succ = true;memset( Flag, -1, sizeof( Flag));for( int i = 0; i < n; ++i){if( Flag[ i] == -1){Dfs( i, -1, 0);}}
}

经验总结

+ GGG must be a Undirected-Graph; (i.e., any edge a→ba\to ba→b must has a corresponding edge b→ab \to ab→a)
__. for any edge (whatever it is directed or not) a−ba - ba−b, it always shows that a,ba,ba,b must be in different set (i.e., the color of them are distinct); but the Algorithm requires that the edge must be Undirected (due to the store for graph of Linked-List, i.e., any edge a→ba\to ba→b must has a corresponding edge b→ab \to ab→a);
__. if not, e.g., G=(a→b)G = (a \to b)G=(a→b); the function dfs(a)dfs(a)dfs(a) would always force the color of aaa by 000 (cuz the color solution of a Bipartite has two choices, i.e., swap the points in two sets would still be a Bipartite); so, dfs(b)dfs(b)dfs(b) would force color[b]=0color[b]=0color[b]=0, and dfs(a)dfs(a)dfs(a) would also force color[a]=0color[a]=0color[a]=0 which causes a contradiction.

+ Dfs( 0, -1, 0) is Wrong, because GGG maybe not connected.
so, you just iterate its one Sub-Connected-Graph. But, we need iterate its all Sub-Connected-Graph.

匈牙利算法计算最大匹配

Given a unweighted Bipartite-Graph L,R,EL, R, EL,R,E, means that all points divide into two sets L,RL, RL,R, and all edges which are connecting L,RL, RL,R are denoted by EEE, e.g., a edge (a,b)(a,b)(a,b) denotes a undirected edge between a point a∈La \in La∈L and b∈Rb \in Rb∈R

A Match is a set of disjoint edges, that is {(l1,r1),(l2,r2),...}\{ (l_1, r_1), (l_2, r_2), ... \}{(l1​,r1​),(l2​,r2​),...} satisfying li≠lj,and,ri≠rjl_i \neq l_j, and, r_i \neq r_jli​=lj​,and,ri​=rj​, it is somewhat like a bijection (every point whatever within LLL or RRR, either being non-matched (no edge associates it) or it has just one match (only one edge associates it) )

A Maximum-Match is a Match with the greatest cardinality.


Due to ∣aMatch∣≤min(∣L∣,∣R∣)| a \ Match | \leq min( |L|, |R|)∣a Match∣≤min(∣L∣,∣R∣), and given a Match, for any point of LLL, it has at most one edge in the Match. We iterate on LLL

Suppose L=[l1,l2,l3,...,lm]L = [l_1, l_2, l_3, ..., l_m]L=[l1​,l2​,l3​,...,lm​], we stipulate that LiL_iLi​ be a prefix of LLL (e.g., L1=[l1],L2=[l1,l2]L_1 = [l_1], L_2 = [l_1, l_2]L1​=[l1​],L2​=[l1​,l2​]), and GiG_iGi​ be a Bipartite-Graph consists of points Li,RL_i, RLi​,R and edges connecting LiL_iLi​ and RRR, and M(Gi)M( G_i)M(Gi​) denotes all its Maximum-Matches of GiG_iGi​, ∣M(Gi)∣|M(G_i)|∣M(Gi​)∣ is the size of any one Maximum-Match (the number of edges in a Maximum-Match).
(notice that, M(Gm)M(G_m)M(Gm​) is not unique, but their size are the same)

Our goal is to get ∣M(Gm)∣| M( G_m) |∣M(Gm​)∣.

The standard approach is Greedy-Algorithm (it somewhat likes DP) ,that is, we get ∣M(G1)∣|M(G_1)|∣M(G1​)∣, and then used to updated the ∣M(G2)∣|M(G_2)|∣M(G2​)∣, until to get the final goal ∣M(Gm)∣|M(G_m)|∣M(Gm​)∣.

  • ∣M(G1)∣|M(G_1)|∣M(G1​)∣ is available.
  • If we got ∣M(Gi)∣|M(G_i)|∣M(Gi​)∣, then ∣M(Gi+1)∣|M(G_{i+1})|∣M(Gi+1​)∣ either equals to it or one more than it.
    The former case means whichever the graph of M(Gi)M(G_i)M(Gi​) is, and whatever the edge (li+1,R)(l_{i+1}, R)(li+1​,R) you choose, they will always contradicts each other.

    The graph is (l1, r1) (l1, r2) (l2, r1) (l2, r2) (l3, r1) (l3, r2)|M( G_2)| is `2`, M( G_2) is either `l1-r1, l2-r2` or `l1-r2, l2-r1`.
    |M( G_3)| is also `2`, whatever the M( G_2) is (two possibles) and whatever the (l3,R) is (tow possibles), the combination of them is always contradictory.
    ... so, M( G_3) has 6 cases: M( G_2) or `l1-r1, l3-r2` or `l1-r2, r3-r1` or `l2-r1, l3-r2` or `l2-r2, l3-r1`
    

    While the latter case means that, there exists a edge (li+1,R)(l_{i+1}, R)(li+1​,R) and a Match (set of edges, because M(Gi)M( G_i)M(Gi​) has multiple specific Match) of M(Gi)M( G_i)M(Gi​), the combination of them is not contradictory.

    The graph is (l1, r1) (l1, r2) (l2, r1) (l2, r2)|M( G_1)| is `1`, M( G_1) is either `l1-r1` or `l1-r2`.
    |M( G_1)| is `2`, if we choose `M( G_1) is `l1-r1 and (l2,r2)` or `M( G_1) is `l1-r2` and (l2,r1)`.
    

pseudocode

for( g : M( G_i)){for( e : E( l_i+1, R)){if( e not contradicts g){|M( G_i+1)| = |M( G_i)| + 1;return;}}
}//> otherwise
|M( G_i+1)| = |M( G_i)|;

But in practice, to storing M(Gi)M( G_i)M(Gi​) is infeasible. We should analysis further. The thought is that can we replace for( g : M( G_i)) by just a ggg, that is, we use one Match instead of iterating all Matches, to get the same effect.

Supposing now we got M(Gi)M( G_i)M(Gi​) and need to calculate M(Gi+1)M( G_{i+1})M(Gi+1​)

l1    r1
l2    r2
l3    r3
.     .
.     .
li    ri
li+1  ri+1
.     .
.     .

For a Match mmm in M(Gi)M(G_i)M(Gi​), the total points under consideration is {l1,...,li,}∪R\{ l_1, ..., l_i, \} \cup R{l1​,...,li​,}∪R, a point is called free if it is not within mmm (i.e., no edge in mmm connects it), otherwise a point is called matched.

A Semi-Augmented-Path of mmm is a path of the form as,b,a,b,....a,b,aea_s, b, a, b, .... a, b, a_eas​,b,a,b,....a,b,ae​ (aaa has two choices lorrl \ or \ rl or r and then bbb is rorlr \ or \ lr or l respectively), satisfying every adjacent pair (a,b)(a,b)(a,b) is a edge of mmm, aea_eae​ is free and all aaa are pairwise distinct. (if the length is greater than 111, asa_sas​ is matched)

It’s meaning is that, if we use the edge bi,aib_i,a_ibi​,ai​ to replace this preceding ai−1,bia_{i-1}, b_iai−1​,bi​, then we have get a distinct Match which has the same cardinality with mmm.
In the other words, the symmetric difference of mmm (a set of edges) and a S-A-Path (set of all adjacent edge in the path) means a new Match. In the new-Match, asa_sas​ becomes free and aea_eae​ becomes matched.

It also called asa_sas​ has a Semi-Augmented-Path as−...a_s- ...as​−....

  • Two matches in M(Gi)M(G_i)M(Gi​) are distinct, if their point-set are distinct.
  • Two distinct matches in M(Gi)M(G_i)M(Gi​) can be transformed to each other by a series of Semi-Augmented-Path .
  • A matched point maybe not exists a Semi-Augmented-Path or multiple.
  • Usually, asa_sas​ belongs to RRR; and specially if asa_sas​ is free, then (as)(a_s)(as​) is also a Semi-A-Path
Match: (l1-r1, l2-r2) and (l1-r2, l2-r1) are same (the point-set are same)For a Graph (l1-r1, l1-r2, l2-r2, l2-l3), there are 3 matches in M(G):
+ m1: (l1-r1, l2-r2)
+ m2: (l1-r1, l2-r3)
+ m3: (l1-r2, l2-r3)For `m1` (only `r3` is free):
+ there is a `Semi-Augmented-Path` (r2-l2-r3), this path means the Match `m2` (if you use `l2-r3` to replace `r2-l2`)
+ there is a `Semi-Augmented-Path` (r1-l1-r2-l2-r3), this path means the Match `m3` (if you use `l1-r2` to replace `r1-l1`, and `l2-r3` replace `r2-l2`)

Property-1:
For a M(g)M(g)M(g), a Match mmm of M(G)M(G)M(G), and its points set is {a,b,c....}\{ a, b, c.... \}{a,b,c....}, and another Match nnn of M(G)M(G)M(G) and its points set is not contains aaa. Then suppose the set of Transform-S-A-Path is p1,p2,p3p1, p2, p3p1,p2,p3 (i.e., if mmm is operated by these path, it will becomes nnn), then, these must exists a pipipi which starts at aaa.

Property-11:
For a Semi-A-Path a1−b1−a2−b2−a3−b3−a4a_1-b_1-a_2-b_2-a_3-b_3-a_4a1​−b1​−a2​−b2​−a3​−b3​−a4​ in mmm (every ai−bia_i-b_iai​−bi​ is contained in mmm will be replaced by bi−ai+1b_i-a_{i+1}bi​−ai+1​ , a4a_4a4​ is free, once aia_iai​ is fixed, then bib_ibi​ is unique, so bib_ibi​ is totally depended on aia_iai​)
a2−b2−a3−b3−a4a_2-b_2-a_3-b_3-a4a2​−b2​−a3​−b3​−a4, and a3−b3−a4a_3-b_3-a_4a3​−b3​−a4​ and a4a_4a4​ are also Semi-A-Path.


A Augmented-Path of mmm is a path of the form bs,(a1,b,...,a,b,ae)b_s, (a_1,b,...,a,b,a_e)bs​,(a1​,b,...,a,b,ae​) where the tail (a1,b,..,ae)(a_1,b,..,a_e)(a1​,b,..,ae​) is a Semi-Augmented-Path , bsb_sbs​ belongs to LLL, and bsb_sbs​ is a new-point.
A new-point is different from total-point, for example, for a Sub-Graph G(3)G(3)G(3) (l1, l2, l3, R), a Match mmm of its Maximum-Matching M(G(3))M(G(3))M(G(3)) (e.g., (l1,r1),(l2,r2)(l1,r1), (l2,r2)(l1,r1),(l2,r2))
Then, l1,l2,l3,Rl1, l2, l3, Rl1,l2,l3,R is total-points of mmm, l1,l2l1, l2l1,l2 is matched, l3,r3,r4,r5,...l3, r3, r4, r5, ...l3,r3,r4,r5,... is free. A new point is a point not l1,l2,l3l1, l2, l3l1,l2,l3 (e.g., l4l4l4)

It means that mmm transformed to m1m1m1 by (a1,b,...,ae)(a1,b,...,a_e)(a1,b,...,ae​) (a1a1a1 is matched in mmm and free in m1m1m1), and then the edge bs,a1b_s, a1bs​,a1 is not contradicts with m1m1m1 (because a1a1a1 is free in m1m1m1, bsb_sbs​ is new-point)

Graph: (l1-r1, l1-r2, l2-r2, l2-r3, l3-r1, l3-r4)|M(G_2)| has  Matches: (l1-r1, l2-r2), (l1-r1, l2-r3), (l1-r2, l2-r3)
Let m be a Match of M(G_2) is (l1-r1, l2-r2), the Augmented-Path of `l3`:
+ `l3-r4` is a Augmented-Path
+ `l3-r1-l1-r2-l2-r3` is also, it means `m` transforms to (l1-r2, l2-r3), then `r1` becomes free, so `l3-r1` is not contradictory to the new Match.

Property-2:
∣M(Gi+1)∣=∣M(Gi)∣+1⇔li+1|M(G_{i+1})| = |M(G_i)| + 1 \quad \Leftrightarrow l_{i+1}∣M(Gi+1​)∣=∣M(Gi​)∣+1⇔li+1​ exists a Augmented-Path in any Match of M(Gi)M(G_i)M(Gi​).
∣M(Gi+1)∣=∣M(Gi)∣⇔li+1|M(G_{i+1})| = |M(G_i)| \quad \quad \ \ \ \Leftrightarrow l_{i+1}∣M(Gi+1​)∣=∣M(Gi​)∣   ⇔li+1​ not exists a Augmented-Path in any Match of M(Gi)M(G_i)M(Gi​).

p:∣M(Gi+1)∣=∣M(Gi)∣+1p: |M(G_{i+1})| = |M(G_i)| + 1p:∣M(Gi+1​)∣=∣M(Gi​)∣+1, q:letmbeanyMatchofM(Gi),thenli+1hasaAugmented−Pathinmq: let\ m\ be\ any\ Match\ of\ M(G_i),\ then\ l_{i+1}\ has\ a\ Augmented-Path\ in\ mq:let m be any Match of M(Gi​), then li+1​ has a Augmented−Path in m
p→qp \to qp→q: according to the definition of ppp, there exist a Match m1m1m1 of M(Gi)M(G_i)M(Gi​) and a edge (li+1,rk)(l_{i+1}, r_k)(li+1​,rk​) (rkr_krk​ is free)
Let mmm be any Match of M(Gi)M(G_i)M(Gi​), if rkr_krk​ is free in mmm, then li+1,rkl_{i+1}, r_kli+1​,rk​ is Augmented-Path; otherwise, there must exists Semi-A-Path of rkr_krk​ in mmm (according to Property-1), to transform mmm to m2m2m2 (m2m2m2 maybe equals to m1m1m1, also may not) where rkr_krk​ is free, then li+1−l_{i+1} -li+1​−Semi-A-Path of rkr_krk​ forms a A-Path in mmm.
q→pq \to pq→p: if the Augmented-Path is the form li+1,rkl_{i+1}, r_kli+1​,rk​, then rkr_krk​ is free, so mmm is not contradictory to edge li+1,rkl_{i+1}, r_kli+1​,rk​, so ∣M(Gi+1)∣=xx+1|M(G_{i+1})| = xx + 1∣M(Gi+1​)∣=xx+1
otherwise, li+1,(rk,l,...,re)l_{i+1}, (r_k, l, ..., r_e)li+1​,(rk​,l,...,re​), then mmm can be transformed to m1m1m1 where rkr_krk​ is free according to Semi-A-Path (rk,...,re)(r_k, ..., r_e)(rk​,...,re​).

Same proof for ∣M(Gi+1)∣=∣M(Gi)∣⇔li+1|M(G_{i+1})| = |M(G_i)| \quad \quad \ \ \ \Leftrightarrow l_{i+1}∣M(Gi+1​)∣=∣M(Gi​)∣   ⇔li+1​ not exists a Augmented-Path in any Match of M(Gi)M(G_i)M(Gi​).


So now, we need not to store all Matched of M(Gi)M(G_i)M(Gi​), but only one Match of it is enough.

Pseudocode

//* points in `L` is [0, m-1], [0, n-1] of `R`.
`M` be a Match.
for( int i = 0; i < m; ++i){if( `i` has a Augmented-Path in `M`){modify `M` according to the Augmented-Path}
}
answer is in `M`

More specifically, we use Match[R]Match[ R]Match[R] to present MMM (Match[r]=lMatch[r] = lMatch[r]=l means there has a edge (l,r)(l,r)(l,r) in MMM)
when i has a A-Path:

  • either the form is i−ri-ri−r, then rrr is free, r has a Semi-A-Path
  • or the form if i−(r1−l1−r2−...rc−lk−rk−le−re)i-(r_1-l_1-r2-...r_c-l_k-r_k-l_e-r_e)i−(r1​−l1​−r2−...rc​−lk​−rk​−le​−re​), then r1r_1r1​ is matched, so we need find a Semi-A-Path of r1r_1r1​ in MMM, it means use l1-r2 to replace r1-l1, … use le-re to replace rk-le, now r1 is free so i-r1 can be added to the Match.
    We use DFS( r1) to find whether r1r_1r1​ has a Semi-A-Path, once we arrive at r_k (DFS(rk)) which has already matched to lel_ele​, we iterate all adjacent points rrr of lel_ele​, once rrr has Semi-A-Path, then modify Match[r]=leMatch[ r] = l_eMatch[r]=le​. the modifying Match[rk]=lkMatch[r_k] = l_kMatch[rk​]=lk​ will be happened in DFS(rc)DFS(r_c)DFS(rc​).
set< int> S; //< all `r` points in the Semi-A-Path, because we need to make sure all `r` are distinct in the path.
bool Has_semiAugmentedPath( int _cur){if( Match[ _cur] == -1){ //< freereturn true;}S.insert( _cur);int l = Match[ _cur]; //< (_cur,l) has also matchedfor( r : Adjacent-Points( l)){if( (r not in S) && Has_semiAugmentedPath( r)){Match[ r] = l; //< (l-r) replace (_cur,l), it is the form (_cur-l-r) in the whole Semi-A-Path.return true;}}S.remove( _cur);return false;
}for( int i = 0; i < m; ++i){for( j : Adjacency-Points( i)){if( Has_semiAugmentedPath( Match[ j])){Match[ j] = i;break;}}
}

But DFS is an Endless-Loop, (e.g., r1−l1−r2−l2−r1r1-l1-r2-l2-r1r1−l1−r2−l2−r1)
We need to prove, for a Match, if rir_iri​ has no Semi-A-Path in one DFS-Prefix-Tree, rir_iri​ is also no Semi-A-Path in all DFS-Prefix-Tree.
e.g., Given a Match, when a DFS-Path is r1−l1−r2−l2−r3−l3r1-l1-r2-l2-r3-l3r1−l1−r2−l2−r3−l3, and l3l3l3 has adjacent-points r1,r2,r3r1, r2, r3r1,r2,r3, due to the prefix-path contains r1,r2,r3r1,r2,r3r1,r2,r3, so l3,r3l3, r3l3,r3 has no Semi-A-Path under the prefix r1−l1−r2r1-l1-r2r1−l1−r2 (we call it that l3,r3l3, r3l3,r3 has no S-A-Path under r1,r2r1,r2r1,r2).

  • Now DFS failed at (r3), we have r3r3r3 has no S-A-Path under r1,r2r1,r2r1,r2 (because l3l3l3 can only choose r1,r2r1, r2r1,r2 which has already occurred) (r3r3r3 may have S-A-Path if the prefix not contains r1,r2r1,r2r1,r2, e.g., r3−l3−l1−r4r3-l3-l1-r4r3−l3−l1−r4 where r4r4r4 is free. it shows that DFS process firstly choose l1−r2l1-r2l1−r2 edge not l1−r4l1-r4l1−r4.)

    A Match:
    l1---r2
    l2---r1
    other edges that are non in the Match is (l1-r1, l2-r2, l1-r3)r2-l1-r1-l2:  now because `l2` can only choose `r2` which has occurred in the prefix-path, so we have `l2,r1` has no S-A-Path under `r2`.
    but `l2,r1` may have S-A-Path if not under `r2`, e.g., `r1-l2-r2-l1-r3` is a valid S-A-Path.
    
  • When DFS failed at (r2) (return back from (r3)), we have r2,r3r2, r3r2,r3 has no S-A-Path except r1r1r1 where the r2r2r2 is reasonable (because its prefix has r1r1r1), but why r3r3r3 is also the same as r2r2r2?
    for mentioned above, we know r3r3r3 has no S-A-Path under r1,r2r1, r2r1,r2, but why it becomes under r1r1r1??
    Proof: if r3r3r3 has S-A-Path under r1r1r1, i.e., (r1)−r3−l3(r1)-r3-l3(r1)−r3−l3, now l3l3l3 can only choose r2r2r2, but now, we know r2r2r2 has no SA-Path under r1r1r1, so this is not feasible.
  • When DFS failed at (r1) (return back from (r2)), we have r1,r2,r3r1,r2,r3r1,r2,r3 has no S-A-Path.
    The proof is similar as above.

We can set a Vis[R]Vis[ R]Vis[R] to denote whether a point of RRR had been visited by DFS. if we found a point is visited, then it has no S-A-Path.
This bool-array is the most vital and sophisticated part of the algorithm.

Given a Match of M(Gi)M(G_i)M(Gi​), we need to check whether li+1l_{i+1}li+1​ has a A-Path, assume that there are edges (li+1,r1/r5)(l_{i+1}, r1/r5)(li+1​,r1/r5)

  • Find whether r1r1r1 has a S-A-Path, if DFS(r1) has visited r2,r3,r4r2, r3, r4r2,r3,r4, then when DFS(r1)DFS(r1)DFS(r1) has ended, we have r1,r2,r3,r4r1,r2,r3,r4r1,r2,r3,r4 has no S-A-Path (corresponds to their Vis[]Vis[]Vis[] is True)
  • Find whether r5r5r5 has a S-A-Path, if DFS(r5) find a Path that is r5,r6,r7r5,r6,r7r5,r6,r7 (but DFS has visited some other points that are failed, e.g., r8,r9r8,r9r8,r9)
    now, we have r8,r9r8, r9r8,r9 has no S-A-Path under r5,...r5,...r5,... (also, their Vis[]Vis[]Vis[] is true), but if the next step (check whether li+2l_{i+2}li+2​ has a A-Path), the Vis[r8,r9]Vis[r8,r9]Vis[r8,r9] should be false. (more detailed, Vis[r8]=trueVis[ r8] = trueVis[r8]=true means r8r8r8 has no S-A-Path under r5,...r5,...r5,..., when we at the next DFS(r10)DFS( r10)DFS(r10) where li+2→r10l_{i+2} \to r10li+2​→r10, when r10r10r10 visits r8r8r8, it would thought that r8r8r8 has no S-A-Path (due to Vis[r8]=trueVis[r8] = trueVis[r8]=true), but Vis[r8]=trueVis[r8] = trueVis[r8]=true not meaning its has no path under r10,..r10,..r10,.., it just means no S-A-Path under r5,...r5,...r5,..., so you should reset Vis[r8]=falseVis[r8] = falseVis[r8]=false when you go to the next li+2l_{i+2}li+2​)
    Also, Vis[r5,r6,r7]Vis[r5,r6,r7]Vis[r5,r6,r7] also should be false (as they already found a S-A-Path)
    But these points are both Vis[]=trueVis[]= trueVis[]=true (means no S-A-Path) at present, so we need to reset them to falsefalsefalse

So, if current-loop has a A-Path, then we need reset all VisVisVis to falsefalsefalse; otherwise, VisVisVis can be inherited.


Lets proceed to discuss reset Vis[r8]=falseVis[r8] = falseVis[r8]=false as mentioned above.
Find that whether there is a A-Path of lil_ili​, if there has edges li→r5l_i \to r5li​→r5 li→r9l_i \to r9li​→r9
... when we are finding S-A-Path of r5r5r5, it involves r5,r4,r3r5, r4, r3r5,r4,r3, and failed then. that means r5,r4,r3r5, r4, r3r5,r4,r3 has no S-A-Path.
... then we will find whether a S-A-Path of r9r9r9, it involves (involve means that those points which are Vis=falseVis = falseVis=false before the operation DFS(r9)DFS( r9)DFS(r9), then becomes Vis=trueVis = trueVis=true after the DFS) r9,r8,r7,r6,r1r9, r8, r7, r6, r1r9,r8,r7,r6,r1 where the S-A-Path is r9,r8,r7r9, r8, r7r9,r8,r7 , now the VisVisVis of them are both truetruetrue. according to discussed above, they should reset to falsefalsefalse.
But, the approach introduces above, will reset all Vis[R]=falseVis[ R] = falseVis[R]=false (including r5,r4,r3r5, r4, r3r5,r4,r3), because the Match-Graph has been modified once we found a S-A-Path.
We need to prove that, we could only modify r9,r8,r7,r6,r1r9, r8, r7, r6, r1r9,r8,r7,r6,r1, not necessary All R.
(r5,r4,r3r5, r4, r3r5,r4,r3 must be matched, let l1,l2,l3l1, l2, l3l1,l2,l3 be the matched-points of them), the A-Path li,r9,l4,r8,l5,r7l_i, r9, l4, r8, l5, r7li​,r9,l4,r8,l5,r7 (this path would modify the previous Match-Graph, we need to prove the modification will not cause that there would be a S-A-Path for r5,r4,r3r5, r4, r3r5,r4,r3 in the new Match-Graph)
+ any point l,rl, rl,r in the A-Path, will not contains any point of l1−r5,l2−r4,l3−r3l1-r5, l2-r4, l3-r3l1−r5,l2−r4,l3−r3
+ any adjacent point of l1,l2,l3l1, l2, l3l1,l2,l3, will not involves ant rrr of the A-Path.
That is, the sub-graph of r5,r4,r3,l1,l2,l3r5,r4,r3,l1,l2,l3r5,r4,r3,l1,l2,l3 (and all edges that connects l1,l2,l3l1,l2,l3l1,l2,l3) and the sub-graph of li,r9,l4,..l_i, r9, l4, ..li​,r9,l4,.. (the A-Path), are totally separated. So, the modification on one sub-graph, will not effect the another sub-graph.

So, we just need to reset r9,...r9, ...r9,... without r3,..r3,..r3,.., we could use a Queue to store all visited R points (i.e., any points Vis=trueVis = trueVis=true will be store in the queue)

例题

+ link

经验总结


We call a bipartite-graph is Full-Matched that the maximal-match equals min(∣L∣,∣R∣)min( |L|, |R|)min(∣L∣,∣R∣);
We call a bipartite is connected that there exists a path l−r1−l1−r2−...−r∀l,rl - r1 - l1 - r2 - ... - r \quad \forall l, rl−r1−l1−r2−...−r∀l,r
As a result, a bipartite is connected→FullMatchedconnected \to FullMatchedconnected→FullMatched (converse is not correct)
Proof
Now, we are at lilili, and there has matched xxx; if x<∣R∣x < |R|x<∣R∣, then there must exists a unmatched point rrr; subsequently, lilili has a A-Path cuz there is a path li−...−rli - ... -rli−...−r.


If lilili has no A-Path (not be matched), then it will not be matched forever. That is, after the whole algorithm, lilili is not be matched.
Proof:
When we are finding A-Path for any LjLjLj where j>ij > ij>i, essentially finding a S-A-Path r−l−r−l−...−rr-l-r-l-...-rr−l−r−l−...−r where every edge r−lr-lr−l is be matched. Because lilili not be matched, it will never occurs in any S-A-Path. Therefore, lilili would be matched forever.

点覆盖

+ A Point-Coverage SSS, its complementary-set V−SV - SV−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→Sis 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−SV-SV−S of a Minimum-Point-Coverage SSS, is always be a Maximum-Independent-Set;

在二分图中

let mmm be the maximal-match, cuz these mmm edges are disjoint, ∣S∣|S|∣S∣ must ≥m\geq m≥m.
Conclusion: ∣S∣=m|S| = m∣S∣=m where SSS is the Minimum-Point-Coverage; and the process for constructing SSS 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 SSS, its complementary-set V−SV - SV−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→Sis 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−SV-SV−S of a Maximum-Independent-Set SSS, is always be a Minimum-Point-Coverage;
+ ∀a∈S\forall a \in S∀a∈S, aaa may have a adjacent-edge (a−b)(a-b)(a−b) (bbb 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−ba-c-ba−c−b where c∉Sc \notin Sc∈/S is possible;

二分图中

Let the Bipartite (L,R,E)(L, R, E)(L,R,E), mmm be its maximal-match; for the theorem of Minimum-Point-Coverage, we have m=∣S∣m = |S|m=∣S∣ where SSS 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

延伸阅读

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

`Computer-Algorithm` 二分图BipartiteGraph,最大匹配,最小点覆盖,最大独立集相关推荐

  1. 贪心法求树的最小支配集,最小点覆盖,最大独立集

    原文地址(转自 Ashly的博客) 定义: 最小支配集:对于图G = (V, E) 来说,最小支配集指的是从 V 中取尽量少的点组成一个集合, 使得 V 中剩余的点都与取出来的点有边相连.也就是说,设 ...

  2. ssl1341-Asteroids【最大匹配,最小点覆盖,图论】

    正题 大意 一个n*n的矩阵里有m个点,你可以一下打掉一排或以列,求打掉所以点要的最小次数. 如: X.X .X. .X. 显然可以看出只需要打两枪. 解题思路 将行和列分为一个二分图,然后每个点的坐 ...

  3. 【POJ - 2226】Muddy Fields(匈牙利算法 或 网络流dinic,二分图匹配,最小点覆盖,矩阵中优秀的建图方式 )

    题干: Rain has pummeled the cows' field, a rectangular grid of R rows and C columns (1 <= R <= 5 ...

  4. 树形DP求树的最小支配集,最小点覆盖,最大独立集

    转自:https://www.cnblogs.com/Ash-ly/p/5783877.html 一:最小支配集 考虑最小支配集,每个点有两种状态,即属于支配集合或者不属于支配集合,其中不属于支配集合 ...

  5. POJ - 3041 Asteroids 二分图最小点覆盖

    题目链接 二分图一个很重要的定理:看了很多大神的博客表示看不懂为什么,以后再看 最小点覆盖=最大匹配 最小点覆盖就是在二分图里边,选择一个点,将所有与该点相链接的边删去,问最小找多少个点能够把所有的边 ...

  6. UVA11419 SAM I AM —— 最小点覆盖 + 输出覆盖点集

    题目链接:https://vjudge.net/problem/UVA-11419 题解: 1.二分图匹配之最小点覆盖.:把x坐标和y坐标看成是点, 图中的目标看成是边,所以最终的目的是求出用最少的点 ...

  7. 二分图专题系列各大知识点总结(匈牙利,染色法,最大独立集,最小点覆盖,最小路径覆盖)

    本文概论 二分图的判断方法:图中不存在奇数环----->染色法判断二分图不存在矛盾 二分图: 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i, ...

  8. hihocoder 1127 : 二分图三·二分图最小点覆盖和最大独立集

    最大独立集问题: 在图G中选取尽可能多的点,使得任意两个点之间没有连边. 结论:最大独立集的点数 = 总点数 - 二分图最大匹配 证明: 假设最大独立集的点数为|U|,二分图最大匹配的匹配数为|M|, ...

  9. HDU - 1054 Strategic Game(最小点覆盖-二分图最大匹配)

    题目链接:点击查看 题目大意:给出一棵树,现在要在节点上放置士兵,每个士兵可以监视与其所在的节点直接相连的节点,问最少需要多少个士兵才能将整棵树都监视到 题目分析:求最少的节点,以保证每条边都有一个端 ...

最新文章

  1. R将因子类型(Factor)转化为字符串类型(Character)
  2. 信息系统项目管理师:第4章:项目整体管理与变更管理(2)
  3. 决策树和随机森林(下)
  4. Java培训教程:Java中的位移运算符!
  5. MFC SendMessage()函数传递字符串
  6. JMS学习二(简单的ActiveMQ实例)
  7. Delphi clientdataset的详细介绍
  8. 华为nova 8 Pro 4G现身官网:同样麒麟985 只是没有5G
  9. 嵌入式电路设计(第一个商业pcb电路图绘制)
  10. 网络协议分析(Network Protocol Analysis)之点到链路控制协议LCP
  11. 光耦驱动单向可控硅_单向可控硅最筒单电路图大全
  12. UOS U盘已经复制成功,有时卡死
  13. Java实现Map集合二级联动
  14. MATLAB设置使用语言为中文
  15. 七种方法绕过安卓手机锁屏
  16. sp经营许可证适用范围是什么?
  17. 每日思考第 76 期:真正的死亡是被人遗忘
  18. 水仙花数(调用函数)
  19. linux mint 17.3中文输入法,linux mint17 中文输入法 五笔(or 拼音)
  20. [游戏]求生之路新地图安装说明

热门文章

  1. python的字典生成工具
  2. android 播放3gp音频,说说 Android 中如何操作音频与视频文件
  3. 绿联USB4扩展坞,VL830拆解分析
  4. 说说Java生态圈的那些事儿
  5. Kerberos协议认证
  6. kafka权限认证ssl
  7. 企业如何实现OA办公系统的最大化应用价值?
  8. 【BZOJ4889】[Tjoi2017]不勤劳的图书管理员 分块+树状数组
  9. 2021年--中国工商银行软件开发中心--社会招聘(春季)
  10. PostgreSQL权限修改 : ALTER DEFAULT PRIVILEGES