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

术语

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

--

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 ljli=lj and r i ≠ r j ri \neq rjri=rj.

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

--

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

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 SS 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;

二分图

Given a Bipartite-Graph ( L , R , E ) (L, R, E)(L,R,E) where E EE is undirected, in the algorithm, it would be stored in the form ( L , R , E 1 ) (L, R, E1)(L,R,E1) where a undirected-edge ∀ ( a − b ) ∈ E \forall (a-b) \in E(ab)E (let a ∈ L a \in LaL, if not swap(a,b)) corresponding to a directed-edge ( a → b ) ∈ E 1 (a\to b) \in E1(ab)E1; we call such a graph be Standard-Bipartite-Graph;
+ An edge a → b a\to bab in Standard-Bipartite-Graph, corresponds to an Undirected-Edge ( a − b ) (a-b)(ab) 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 , R L,RL,R-Sets in the below way:

0 1 0 1 0
1 0 1 0
0 1 0
1 0
0

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

. For instance, if all edges are a − b a-bab where let a = ( x , y ) a=(x,y)a=(x,y) then b bb 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 , B A, 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 : B 13:A, 24:B13:A,24:B or 13 : B , 24 : A 13: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 A AA into a Set-A, and the same process for B BB, then the Graph is absolutely same to the Original-Graph (we just change its appearance)
A:( ...) B: ( ...), then there are no edge within A AA or B BB, alternatively, all edges of G GG are the form of connecting one point of A AA to one point of B BB.
This form is not unique (e.g., for a isolated point, it can belongs to A AA or B BB)


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 = ( G   i s   B i p a r t i t e ) , q = ( n o   o d d _ l o o p   i n   G ) p = (G \ is \ Bipartite), q = (no \ odd\_loop \ in\ G)p=(G is Bipartite),q=(no odd_loop in G), then we have p → q p \to qpq, 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 → p q \to pqp 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 G GG maybe not connected, suppose that G GG has several connected Sub-Graphs G 1 , G 2 , G 3 G1, 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 F l a g [ ] 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);
        }
    }
}

经验总结

+ G GG must be a Undirected-Graph; (i.e., any edge a → b a\to bab must has a corresponding edge b → a b \to aba)
__. for any edge (whatever it is directed or not) a − b a - bab, it always shows that a , b a,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 → b a\to bab must has a corresponding edge b → a b \to aba);
__. if not, e.g., G = ( a → b ) G = (a \to b)G=(ab); the function d f s ( a ) dfs(a)dfs(a) would always force the color of a aa by 0 00 (cuz the color solution of a Bipartite has two choices, i.e., swap the points in two sets would still be a Bipartite); so, d f s ( b ) dfs(b)dfs(b) would force c o l o r [ b ] = 0 color[b]=0color[b]=0, and d f s ( a ) dfs(a)dfs(a) would also force c o l o r [ a ] = 0 color[a]=0color[a]=0 which causes a contradiction.

+ Dfs( 0, -1, 0) is Wrong, because G GG 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 , E L, R, EL,R,E, means that all points divide into two sets L , R L, RL,R, and all edges which are connecting L , R L, RL,R are denoted by E EE, e.g., a edge ( a , b ) (a,b)(a,b) denotes a undirected edge between a point a ∈ L a \in LaL and b ∈ R b \in RbR

A Match is a set of disjoint edges, that is { ( l 1 , r 1 ) , ( l 2 , r 2 ) , . . . } \{ (l_1, r_1), (l_2, r_2), ... \}{(l1,r1),(l2,r2),...} satisfying l i ≠ l j , a n d , r i ≠ r j l_i \neq l_j, and, r_i \neq r_jli=lj,and,ri=rj, it is somewhat like a bijection (every point whatever within L LL or R RR, 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 ∣ a   M a t c h ∣ ≤ m i n ( ∣ L ∣ , ∣ R ∣ ) | a \ Match | \leq min( |L|, |R|)a Matchmin(L,R), and given a Match, for any point of L LL, it has at most one edge in the Match. We iterate on L LL

Suppose L = [ l 1 , l 2 , l 3 , . . . , l m ] L = [l_1, l_2, l_3, ..., l_m]L=[l1,l2,l3,...,lm], we stipulate that L i L_iLi be a prefix of L LL (e.g., L 1 = [ l 1 ] , L 2 = [ l 1 , l 2 ] L_1 = [l_1], L_2 = [l_1, l_2]L1=[l1],L2=[l1,l2]), and G i G_iGi be a Bipartite-Graph consists of points L i , R L_i, RLi,R and edges connecting L i L_iLi and R RR, and M ( G i ) M( G_i)M(Gi) denotes all its Maximum-Matches of G i G_iGi, ∣ M ( G i ) ∣ |M(G_i)|M(Gi) is the size of any one Maximum-Match (the number of edges in a Maximum-Match).
(notice that, M ( G m ) M(G_m)M(Gm) is not unique, but their size are the same)

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

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

  • ∣ M ( G 1 ) ∣ |M(G_1)|M(G1) is available.
  • If we got ∣ M ( G i ) ∣ |M(G_i)|M(Gi), then ∣ M ( G i + 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 ( G i ) M(G_i)M(Gi) is, and whatever the edge ( l i + 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 ( l i + 1 , R ) (l_{i+1}, R)(li+1,R) and a Match (set of edges, because M ( G i ) M( G_i)M(Gi) has multiple specific Match) of M ( G i ) 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 ( G i ) 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 g gg, that is, we use one Match instead of iterating all Matches, to get the same effect.

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

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

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

A Semi-Augmented-Path of m mm is a path of the form a s , b , a , b , . . . . a , b , a e a_s, b, a, b, .... a, b, a_eas,b,a,b,....a,b,ae (a aa has two choices l   o r   r l \ or \ rl or r and then b bb is r   o r   l r \ or \ lr or l respectively), satisfying every adjacent pair ( a , b ) (a,b)(a,b) is a edge of m mm, a e a_eae is free and all a aa are pairwise distinct. (if the length is greater than 1 11, a s a_sas is matched)

It’s meaning is that, if we use the edge b i , a i b_i,a_ibi,ai to replace this preceding a i − 1 , b i a_{i-1}, b_iai1,bi, then we have get a distinct Match which has the same cardinality with m mm.
In the other words, the symmetric difference of m mm (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, a s a_sas becomes free and a e a_eae becomes matched.

It also called a s a_sas has a Semi-Augmented-Path a s − . . . a_s- ...as....

  • Two matches in M ( G i ) M(G_i)M(Gi) are distinct, if their point-set are distinct.
  • Two distinct matches in M ( G i ) 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, a s a_sas belongs to R RR; and specially if a s a_sas is free, then ( a s ) (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 m mm of M ( G ) M(G)M(G), and its points set is { a , b , c . . . . } \{ a, b, c.... \}{a,b,c....}, and another Match n nn of M ( G ) M(G)M(G) and its points set is not contains a aa. Then suppose the set of Transform-S-A-Path is p 1 , p 2 , p 3 p1, p2, p3p1,p2,p3 (i.e., if m mm is operated by these path, it will becomes n nn), then, these must exists a p i pipi which starts at a aa.

Property-11:
For a Semi-A-Path a 1 − b 1 − a 2 − b 2 − a 3 − b 3 − a 4 a_1-b_1-a_2-b_2-a_3-b_3-a_4a1b1a2b2a3b3a4 in m mm (every a i − b i a_i-b_iaibi is contained in m mm will be replaced by b i − a i + 1 b_i-a_{i+1}biai+1 , a 4 a_4a4 is free, once a i a_iai is fixed, then b i b_ibi is unique, so b i b_ibi is totally depended on a i a_iai)
a 2 − b 2 − a 3 − b 3 − a 4 a_2-b_2-a_3-b_3-a4a2b2a3b3a4, and a 3 − b 3 − a 4 a_3-b_3-a_4a3b3a4 and a 4 a_4a4 are also Semi-A-Path.


A Augmented-Path of m mm is a path of the form b s , ( a 1 , b , . . . , a , b , a e ) b_s, (a_1,b,...,a,b,a_e)bs,(a1,b,...,a,b,ae) where the tail ( a 1 , b , . . , a e ) (a_1,b,..,a_e)(a1,b,..,ae) is a Semi-Augmented-Path , b s b_sbs belongs to L LL, and b s b_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 m mm of its Maximum-Matching M ( G ( 3 ) ) M(G(3))M(G(3)) (e.g., ( l 1 , r 1 ) , ( l 2 , r 2 ) (l1,r1), (l2,r2)(l1,r1),(l2,r2))
Then, l 1 , l 2 , l 3 , R l1, l2, l3, Rl1,l2,l3,R is total-points of m mm, l 1 , l 2 l1, l2l1,l2 is matched, l 3 , r 3 , r 4 , r 5 , . . . l3, r3, r4, r5, ...l3,r3,r4,r5,... is free. A new point is a point not l 1 , l 2 , l 3 l1, l2, l3l1,l2,l3 (e.g., l 4 l4l4)

It means that m mm transformed to m 1 m1m1 by ( a 1 , b , . . . , a e ) (a1,b,...,a_e)(a1,b,...,ae) (a 1 a1a1 is matched in m mm and free in m 1 m1m1), and then the edge b s , a 1 b_s, a1bs,a1 is not contradicts with m 1 m1m1 (because a 1 a1a1 is free in m 1 m1m1, b s b_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 ( G i + 1 ) ∣ = ∣ M ( G i ) ∣ + 1 ⇔ l i + 1 |M(G_{i+1})| = |M(G_i)| + 1 \quad \Leftrightarrow l_{i+1}M(Gi+1)=M(Gi)+1li+1 exists a Augmented-Path in any Match of M ( G i ) M(G_i)M(Gi).
∣ M ( G i + 1 ) ∣ = ∣ M ( G i ) ∣     ⇔ l i + 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 ( G i ) M(G_i)M(Gi).

p : ∣ M ( G i + 1 ) ∣ = ∣ M ( G i ) ∣ + 1 p: |M(G_{i+1})| = |M(G_i)| + 1p:M(Gi+1)=M(Gi)+1, q : l e t   m   b e   a n y   M a t c h   o f   M ( G i ) ,   t h e n   l i + 1   h a s   a   A u g m e n t e d − P a t h   i n   m q: 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 AugmentedPath in m
p → q p \to qpq: according to the definition of p pp, there exist a Match m 1 m1m1 of M ( G i ) M(G_i)M(Gi) and a edge ( l i + 1 , r k ) (l_{i+1}, r_k)(li+1,rk) (r k r_krk is free)
Let m mm be any Match of M ( G i ) M(G_i)M(Gi), if r k r_krk is free in m mm, then l i + 1 , r k l_{i+1}, r_kli+1,rk is Augmented-Path; otherwise, there must exists Semi-A-Path of r k r_krk in m mm (according to Property-1), to transform m mm to m 2 m2m2 (m 2 m2m2 maybe equals to m 1 m1m1, also may not) where r k r_krk is free, then l i + 1 − l_{i+1} -li+1Semi-A-Path of r k r_krk forms a A-Path in m mm.
q → p q \to pqp: if the Augmented-Path is the form l i + 1 , r k l_{i+1}, r_kli+1,rk, then r k r_krk is free, so m mm is not contradictory to edge l i + 1 , r k l_{i+1}, r_kli+1,rk, so ∣ M ( G i + 1 ) ∣ = x x + 1 |M(G_{i+1})| = xx + 1M(Gi+1)=xx+1
otherwise, l i + 1 , ( r k , l , . . . , r e ) l_{i+1}, (r_k, l, ..., r_e)li+1,(rk,l,...,re), then m mm can be transformed to m 1 m1m1 where r k r_krk is free according to Semi-A-Path ( r k , . . . , r e ) (r_k, ..., r_e)(rk,...,re).

Same proof for ∣ M ( G i + 1 ) ∣ = ∣ M ( G i ) ∣     ⇔ l i + 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 ( G i ) M(G_i)M(Gi).


So now, we need not to store all Matched of M ( G i ) 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 M a t c h [ R ] Match[ R]Match[R] to present M MM (M a t c h [ r ] = l Match[r] = lMatch[r]=l means there has a edge ( l , r ) (l,r)(l,r) in M MM)
when i has a A-Path:

  • either the form is i − r i-rir, then r rr is free, r has a Semi-A-Path
  • or the form if i − ( r 1 − l 1 − r 2 − . . . r c − l k − r k − l e − r e ) i-(r_1-l_1-r2-...r_c-l_k-r_k-l_e-r_e)i(r1l1r2...rclkrklere), then r 1 r_1r1 is matched, so we need find a Semi-A-Path of r 1 r_1r1 in M MM, 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 r 1 r_1r1 has a Semi-A-Path, once we arrive at r_k (DFS(rk)) which has already matched to l e l_ele, we iterate all adjacent points r rr of l e l_ele, once r rr has Semi-A-Path, then modify M a t c h [ r ] = l e Match[ r] = l_eMatch[r]=le. the modifying M a t c h [ r k ] = l k Match[r_k] = l_kMatch[rk]=lk will be happened in D F S ( r c ) 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){ //< free
		return true;
	}
	S.insert( _cur);
	int l = Match[ _cur]; //< (_cur,l) has also matched
	for( 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., r 1 − l 1 − r 2 − l 2 − r 1 r1-l1-r2-l2-r1r1l1r2l2r1)
We need to prove, for a Match, if r i r_iri has no Semi-A-Path in one DFS-Prefix-Tree, r i r_iri is also no Semi-A-Path in all DFS-Prefix-Tree.
e.g., Given a Match, when a DFS-Path is r 1 − l 1 − r 2 − l 2 − r 3 − l 3 r1-l1-r2-l2-r3-l3r1l1r2l2r3l3, and l 3 l3l3 has adjacent-points r 1 , r 2 , r 3 r1, r2, r3r1,r2,r3, due to the prefix-path contains r 1 , r 2 , r 3 r1,r2,r3r1,r2,r3, so l 3 , r 3 l3, r3l3,r3 has no Semi-A-Path under the prefix r 1 − l 1 − r 2 r1-l1-r2r1l1r2 (we call it that l 3 , r 3 l3, r3l3,r3 has no S-A-Path under r 1 , r 2 r1,r2r1,r2).

  • Now DFS failed at (r3), we have r 3 r3r3 has no S-A-Path under r 1 , r 2 r1,r2r1,r2 (because l 3 l3l3 can only choose r 1 , r 2 r1, r2r1,r2 which has already occurred) (r 3 r3r3 may have S-A-Path if the prefix not contains r 1 , r 2 r1,r2r1,r2, e.g., r 3 − l 3 − l 1 − r 4 r3-l3-l1-r4r3l3l1r4 where r 4 r4r4 is free. it shows that DFS process firstly choose l 1 − r 2 l1-r2l1r2 edge not l 1 − r 4 l1-r4l1r4.)
    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 r 2 , r 3 r2, r3r2,r3 has no S-A-Path except r 1 r1r1 where the r 2 r2r2 is reasonable (because its prefix has r 1 r1r1), but why r 3 r3r3 is also the same as r 2 r2r2?
    for mentioned above, we know r 3 r3r3 has no S-A-Path under r 1 , r 2 r1, r2r1,r2, but why it becomes under r 1 r1r1??
    Proof: if r 3 r3r3 has S-A-Path under r 1 r1r1, i.e., ( r 1 ) − r 3 − l 3 (r1)-r3-l3(r1)r3l3, now l 3 l3l3 can only choose r 2 r2r2, but now, we know r 2 r2r2 has no SA-Path under r 1 r1r1, so this is not feasible.
  • When DFS failed at (r1) (return back from (r2)), we have r 1 , r 2 , r 3 r1,r2,r3r1,r2,r3 has no S-A-Path.
    The proof is similar as above.

We can set a V i s [ R ] Vis[ R]Vis[R] to denote whether a point of R RR 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 ( G i ) M(G_i)M(Gi), we need to check whether l i + 1 l_{i+1}li+1 has a A-Path, assume that there are edges ( l i + 1 , r 1 / r 5 ) (l_{i+1}, r1/r5)(li+1,r1/r5)

  • Find whether r 1 r1r1 has a S-A-Path, if DFS(r1) has visited r 2 , r 3 , r 4 r2, r3, r4r2,r3,r4, then when D F S ( r 1 ) DFS(r1)DFS(r1) has ended, we have r 1 , r 2 , r 3 , r 4 r1,r2,r3,r4r1,r2,r3,r4 has no S-A-Path (corresponds to their V i s [ ] Vis[]Vis[] is True)
  • Find whether r 5 r5r5 has a S-A-Path, if DFS(r5) find a Path that is r 5 , r 6 , r 7 r5,r6,r7r5,r6,r7 (but DFS has visited some other points that are failed, e.g., r 8 , r 9 r8,r9r8,r9)
    now, we have r 8 , r 9 r8, r9r8,r9 has no S-A-Path under r 5 , . . . r5,...r5,... (also, their V i s [ ] Vis[]Vis[] is true), but if the next step (check whether l i + 2 l_{i+2}li+2 has a A-Path), the V i s [ r 8 , r 9 ] Vis[r8,r9]Vis[r8,r9] should be false. (more detailed, V i s [ r 8 ] = t r u e Vis[ r8] = trueVis[r8]=true means r 8 r8r8 has no S-A-Path under r 5 , . . . r5,...r5,..., when we at the next D F S ( r 10 ) DFS( r10)DFS(r10) where l i + 2 → r 10 l_{i+2} \to r10li+2r10, when r 10 r10r10 visits r 8 r8r8, it would thought that r 8 r8r8 has no S-A-Path (due to V i s [ r 8 ] = t r u e Vis[r8] = trueVis[r8]=true), but V i s [ r 8 ] = t r u e Vis[r8] = trueVis[r8]=true not meaning its has no path under r 10 , . . r10,..r10,.., it just means no S-A-Path under r 5 , . . . r5,...r5,..., so you should reset V i s [ r 8 ] = f a l s e Vis[r8] = falseVis[r8]=false when you go to the next l i + 2 l_{i+2}li+2)
    Also, V i s [ r 5 , r 6 , r 7 ] 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 V i s [ ] = t r u e Vis[]= trueVis[]=true (means no S-A-Path) at present, so we need to reset them to f a l s e falsefalse

So, if current-loop has a A-Path, then we need reset all V i s VisVis to f a l s e falsefalse; otherwise, V i s VisVis can be inherited.


Lets proceed to discuss reset V i s [ r 8 ] = f a l s e Vis[r8] = falseVis[r8]=false as mentioned above.
Find that whether there is a A-Path of l i l_ili, if there has edges l i → r 5 l_i \to r5lir5 l i → r 9 l_i \to r9lir9
... when we are finding S-A-Path of r 5 r5r5, it involves r 5 , r 4 , r 3 r5, r4, r3r5,r4,r3, and failed then. that means r 5 , r 4 , r 3 r5, r4, r3r5,r4,r3 has no S-A-Path.
... then we will find whether a S-A-Path of r 9 r9r9, it involves (involve means that those points which are V i s = f a l s e Vis = falseVis=false before the operation D F S ( r 9 ) DFS( r9)DFS(r9), then becomes V i s = t r u e Vis = trueVis=true after the DFS) r 9 , r 8 , r 7 , r 6 , r 1 r9, r8, r7, r6, r1r9,r8,r7,r6,r1 where the S-A-Path is r 9 , r 8 , r 7 r9, r8, r7r9,r8,r7 , now the V i s VisVis of them are both t r u e truetrue. according to discussed above, they should reset to f a l s e falsefalse.
But, the approach introduces above, will reset all V i s [ R ] = f a l s e Vis[ R] = falseVis[R]=false (including r 5 , r 4 , r 3 r5, 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 r 9 , r 8 , r 7 , r 6 , r 1 r9, r8, r7, r6, r1r9,r8,r7,r6,r1, not necessary All R.
(r 5 , r 4 , r 3 r5, r4, r3r5,r4,r3 must be matched, let l 1 , l 2 , l 3 l1, l2, l3l1,l2,l3 be the matched-points of them), the A-Path l i , r 9 , l 4 , r 8 , l 5 , r 7 l_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 r 5 , r 4 , r 3 r5, r4, r3r5,r4,r3 in the new Match-Graph)
+ any point l , r l, rl,r in the A-Path, will not contains any point of l 1 − r 5 , l 2 − r 4 , l 3 − r 3 l1-r5, l2-r4, l3-r3l1r5,l2r4,l3r3
+ any adjacent point of l 1 , l 2 , l 3 l1, l2, l3l1,l2,l3, will not involves ant r rr of the A-Path.
That is, the sub-graph of r 5 , r 4 , r 3 , l 1 , l 2 , l 3 r5,r4,r3,l1,l2,l3r5,r4,r3,l1,l2,l3 (and all edges that connects l 1 , l 2 , l 3 l1,l2,l3l1,l2,l3) and the sub-graph of l i , r 9 , l 4 , . . 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 r 9 , . . . r9, ...r9,... without r 3 , . . r3,..r3,.., we could use a Queue to store all visited R points (i.e., any points V i s = t r u e Vis = trueVis=true will be store in the queue)

例题

+ link

经验总结


We call a bipartite-graph is Full-Matched that the maximal-match equals m i n ( ∣ L ∣ , ∣ R ∣ ) min( |L|, |R|)min(L,R);
We call a bipartite is connected that there exists a path l − r 1 − l 1 − r 2 − . . . − r ∀ l , r l - r1 - l1 - r2 - ... - r \quad \forall l, rlr1l1r2...rl,r
As a result, a bipartite is c o n n e c t e d → F u l l M a t c h e d connected \to FullMatchedconnectedFullMatched (converse is not correct)
Proof
Now, we are at l i lili, and there has matched x xx; if x < ∣ R ∣ x < |R|x<R, then there must exists a unmatched point r rr; subsequently, l i lili has a A-Path cuz there is a path l i − . . . − r li - ... -rli...r.


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

点覆盖

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

在二分图中

let m mm be the maximal-match, cuz these m mm edges are disjoint, ∣ S ∣ |S|S must ≥ m \geq mm.
Conclusion: ∣ S ∣ = m |S| = mS=m where S SS is the Minimum-Point-Coverage; and the process for constructing S SS 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 SS, its complementary-set V − S V - SVS 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-SVS of a Maximum-Independent-Set S SS, is always be a Minimum-Point-Coverage;
+ ∀ a ∈ S \forall a \in SaS, a aa may have a adjacent-edge ( a − b ) (a-b)(ab) (b bb must ∉ S \notin S/S);
. ∀ a , b ∈ S \forall a,b \in Sa,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-bacb where c ∉ S c \notin Sc/S is possible;

二分图中

Let the Bipartite ( L , R , E ) (L, R, E)(L,R,E), m mm be its maximal-match; for the theorem of Minimum-Point-Coverage, we have m = ∣ S ∣ m = |S|m=S where S SS is the Minimum-Point-Coverage; therefore, we have ∣ L ∣ + ∣ R ∣ − m |L| +|R| - mL+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


版权声明:本文为qq_66485519原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。