二分图匹配

 
  
 

 

#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,分为二分图的左侧和右侧。 优先选择左侧序号更小的链接可能的边。 对于两个点的目标点“冲突”的时候,采起“协商”的办法。 即序号小的链接可能链接的另外一条边。 若“协商”失败,则放弃序号较大的点的边。
相关文章
相关标签/搜索