二分圖匹配

 
  
 

 

#include <bits/stdc++.h>
using namespace std; typedef long long LL; inline LL read () { LL res = 0 ; int f (1) ; char ch = getchar (); while (!isdigit(ch)) { if (ch == '-') f = -1 ; ch = getchar(); } while (isdigit(ch)) res = (res << 1) + (res << 3) + (ch ^ 48),ch = getchar(); return res * f ; } const int N = 1e3; bool f[N][N]; bool used[N]; int match[N]; int n,m,e; inline bool DFS(int pos) { for(register int i=1; i<=m; i++) { if(f[pos][i] and !used[i]) { used[i] = true; if(!match[i] or DFS(match[i])) { match[i] = pos; return true; } } } return false; } signed main() { n=read(),m=read(),e=read(); for(register int i=1; i<=e; i++) { int x=read(),y=read(); if(x<=n and y<=m) f[x][y] = true; } int ans = 0; for(register int i=1; i<=n; i++) { memset(used,false,sizeof(used)); if(DFS(i)) ans++; } cout << ans << endl ; return 0; }

 

1、二分圖

對於一個圖G=(V,E),若能將其點集分爲兩個互不相交的兩個子集X、Y, 使得X∩Y=∅,且對於G的邊集V,若其全部邊的頂點所有一側屬於X, 一側屬於Y,則稱圖G爲一個二分圖。

2、定理:

當且僅當無向圖G的迴路個數爲偶數時,圖G爲一個二分圖。 無迴路的圖也是二分圖。

3、二分圖斷定:

在二分圖G中,任選一個點V, 使用BFS算出其餘點相對於V的距離(邊權爲1) 對於每一條邊E,枚舉它的兩個端點,若其兩個端點的值, 一個爲奇數,一個爲偶數,則圖G爲一個二分圖。

4、匹配:

對於一個二分圖G的子圖M,若M的邊集E的的任意兩條邊都不鏈接同一個頂點, 則稱M爲G的一個匹配。

5、最大匹配

對於二分圖G的一個子圖M,若M爲其邊數最多的子圖, 則稱M爲G的最大匹配。

6、匈牙利算法

一、算法描述:

創建有向圖G,分爲二分圖的左側和右側。 優先選擇左側序號更小的鏈接可能的邊。 對於兩個點的目標點「衝突」的時候,採起「協商」的辦法。 即序號小的鏈接可能鏈接的另外一條邊。 若「協商」失敗,則放棄序號較大的點的邊。
相關文章
相關標籤/搜索