zoukankan      html  css  js  c++  java
  • 【学习】Hall’s Marriage Theorem

    其实是在做题时遇到这个定理的。
    这个定理的图论意义是:

    对于一个二分图(G={X+Y,E}),它满足:
    (forall W subseteq X, \, |W| leq |N_G(W)|) (iff)(X)中的每个结点都有匹配.
    其中(N_G(W))为图(G)中所有与(W)相连的结点的集合。

    必要性显然。
    对于充分性,不会……以后再补充。

    由这个定理,我们能得到一个推论:

    二分图(G)的最大匹配(M)等于(|X| - max (|W| - |N_G(W)|)).

    顺便一提,我们允许(W = emptyset),故(max (|W| - |N_G(W)|) geq 0)
    我们分两步来证明这个推论。在此,我们假设(W_0 subseteq X)满足(|W_0| - |N_G(W_0)| = max (|W| - |N_G(W)|))

    • 证明:(M leq |X| - max (|W| - |N_G(W)|)).
      考虑(W_0),即使(N_G(W_0))中的每个结点都与(W_0)中的结点匹配,也会有(|W_0| - |N_G(W_0)|)个结点得不到匹配。故(X)中至少有(|W_0| - |N_G(W_0)|)个结点得不到匹配。因此,(M leq |X| - max (|W|))
    • 证明:(M geq |X| - max (|W| - |N_G(W)|)).
      我们在(Y)中添加(max (|W| - |N_G(W)|)个结点与(X)中所有结点相连得到新图(G`),那么,(|W_0| - |N_{G`}(W_0)| = 0)。由Hall‘s Marriage Theorem可知,图(G`)(X)的每个元素都有匹配。而对于(W_0),因为(|W_0| = |N_{G`}(W_0)|),所以(N_{G`}(W_0))中的每个元素都与(W_0)中的元素匹配,可得我们新加入的结点都有匹配。因此,除(W_0)中有(|W_0|-|N_G(W_0)|)个结点与新加入的结点匹配之外,(X)中其余结点都与原来(Y)中的结点匹配。故在删去新加的结点后,(X)中至多有(|W_0| - |N_G(W_0)|)个结点没有匹配。则(M geq |X| - max (|W| - |N_G(W)|))

    那么,这个定理及其推论有什么用呢?因为要枚举(X)的所有子集,所以一般是没什么用的。然而,某些有特殊性质的二分图的最大匹配问题,会使用这个定理及其推论来转化问题。

    例题

    arc076F Exhausted?

    题意:给出二分图(G={X+Y,E})(X)中的所有结点满足:若其编号为(i),则只与(Y)中编号小于等于(L_i)或编号大于等于(R_i)的结点连边。给出(|X|,|Y|)和所有的(L_i,R_i),求(G)的最大匹配(M)。(输出(|X|-M))
    (|X|,|Y| leq 2 imes 10^5).

    有了这个定理,问题就简单了。我们只要求(max (|W| - |N_G(W)|))。对于(W subseteq X)(N_G(W))就是形如(Y - [l,r])的形式,其中([l,r])(Y)中一个编号的区间。我们枚举(r),用线段树实现区间加和区间查最大值即可。具体做法不再阐述。
    时间复杂度(O(n log n))

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200010;
    int n,m,ans,cnt;
    struct data {
      int l,r;
    } ordl[N],ordr[N];
    bool cmpl(data a,data b) {
      return a.l < b.l;
    }
    bool cmpr(data a,data b) {
      return  a.r < b.r;
    }
    struct node {
      int mx,tag;
    } t[N << 2];
    void puttag(int x,int val) {
      t[x].mx += val;
      t[x].tag += val;
    }
    void push_down(int x) {
      puttag(x<<1,t[x].tag);
      puttag(x<<1|1,t[x].tag);
      t[x].tag = 0;
    }
    void push_up(int x) {
      t[x].mx = max(t[x<<1].mx,t[x<<1|1].mx);
    }
    void modify(int l,int r,int val,int x=1,int lp=1,int rp=m) {
      if (l > rp || r < lp) return;
      if (lp >= l && rp <= r) {
        puttag(x,val);
        return;
      }
      if (t[x].tag) push_down(x);
      int mid = (lp + rp) >> 1;
      modify(l,r,val,x<<1,lp,mid);
      modify(l,r,val,x<<1|1,mid+1,rp);
      push_up(x);
    }
    int query(int l,int r,int x=1,int lp=1,int rp=m) {
      if (l > rp || r < lp) return 0;
      if (lp >= l && rp <= r) return t[x].mx;
      if (t[x].tag) push_down(x);
      int mid = (lp + rp) >> 1;
      return max(query(l,r,x<<1,lp,mid),query(l,r,x<<1|1,mid+1,rp));
    }
    int main() {
      int a,b;
      scanf("%d%d",&n,&m);
      ans = max(0,n - m);
      cnt = n;
      for (int i = 1 ; i <= cnt ; ++ i) {
        scanf("%d%d",&a,&b);
        a ++;
        b --;
        if (a > b) {
          i --, cnt --;
          continue;
        }
        ordl[i] = (data) {a,b};
        ordr[i] = (data) {a,b};
      }
      sort(ordl+1,ordl+cnt+1,cmpl);
      sort(ordr+1,ordr+cnt+1,cmpr);
      int pl = 1, pr = 1;
      for (int i = 1 ; i <= m ; ++ i) {
        modify(1,i,1);
        for (; ordl[pl].l <= i && pl <= cnt ; ++ pl)
          modify(ordl[pl].l,m,1);
        ans = max(ans,query(1,i) - m);
        for (; ordr[pr].r <= i && pr <= cnt ; ++ pr)
          modify(ordr[pr].l,m,-1);
      }
      printf("%d
    ",ans);
      return 0;
    }
    

    小结:学了一个没卵用的定理。也挺好奇还有哪些二分图能用到这个定理。

    upd 2018.12.26

    假如(G)满足,(X)中的每一个结点与(Y)中一个区间内的结点连边,即(forall a in X, N_G(a) = [l_a,r_a])

    定义对于(Y)中的一个编号区间([l,r])(f([l,r]))(X)中只与([l,r])中点连边的点构成的集合,即({ a in X | N_G(a) subseteq [l,r] })

    求证:

    [forall [l,r] subseteq Y, |f([l,r])| leq |[l,r]| iff forall W subseteq X, |W| leq |N_G(W)| ]

    证明:

    • 必要性。令(W = f([l,r])),那显然有(N_G(W) subseteq [l,r])。因此,(|f([l,r])| = |W| leq |N_G(W)| leq |[l,r]|)
    • 充分性。考虑任意一个(W subseteq X),那么(N_G(W)= igcup_{a in W} [l_a,r_a])。那么,(N_G(W))就一定可以被表示为若干个互不相交的区间的并。因为每个(X)中的结点都只和一个区间内的点连边,所以我们可以把(W)划分为若干个集合,其中每个集合对应(N_G(W))中的一段区间。对于我们划分出来的任意一个集合,假如它对应的区间为([l,r]),那这个集合就一定是(f([l,r]))的子集。因此,对于(W)划分出来的每一集合(S)都满足(|S| leq |N_G(S)|),故(W)也满足(|W| leq |N_G(W)|)
  • 相关阅读:
    济南学习 Day5 T3 晚
    Codevs 1043 ==洛谷 P1004 方格取数
    济南学习 Day 5 T2 晚
    济南学习 Day 5 T1 晚
    济南学习 Day 5 T3 am
    济南学习 Day 5 T2 am
    LeetCode Weekly Contest 8
    poj-1410 Intersection
    leetcode-Warm Up Contest-Aug.21
    poj-1384 Piggy-Bank
  • 原文地址:https://www.cnblogs.com/cly-none/p/Hall_Theorem.html
Copyright © 2011-2022 走看看