AcWing 861. 二分图的最大匹配 -JAVA
原题链接
简单
作者:
acw_weian
,
2020-10-21 14:58:34
,
所有人可见
,
阅读 811
import java.io.*;
import java.util.*;
class Main {
/**
* 要了解匈牙利算法必须先理解下面的概念:
* 匹配:在图论中,一个「匹配」是一个边的集合,其中任意两条边都没有公共顶点。
* 最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
*
* 下面是一些补充概念:
* 完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。
* 交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。
* 增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替 路称为增广路(agumenting path)。
*
* 匈牙利算法思路:
* 每个点从另一个集合里挑对象,没冲突的话就先安排上,要是冲突了就用增广路径重新匹配。重复上述思路,
* 直到所有的点都找到对象,或者找不到对象也找不到增广路。
*/
static int N = 510;
static BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
static Map<Integer, Set<Integer>> graph = new HashMap(N);
static int[] match = new int[N];
static boolean[] st = new boolean[N];
public static void main(String[] args) throws Exception {
String[] ss = read.readLine().split(" ");
int n1 = Integer.valueOf(ss[0]), n2 = Integer.valueOf(ss[1]), m = Integer.valueOf(ss[2]);
for(int i = 0; i < m; i++){
ss = read.readLine().split(" ");
int a = Integer.valueOf(ss[0]), b = Integer.valueOf(ss[1]);
graph.putIfAbsent(a, new HashSet<>());
graph.get(a).add(b);
}
int cnt = 0;
for(int i = 1; i <= n1; i++){
Arrays.fill(st, false);
if(find(i)) cnt++;
}
System.out.println(cnt);
}
public static boolean find(int left){
if(graph.get(left) == null) return false;
for(Integer right: graph.get(left)){
if(st[right]) continue;
st[right] = true;
if(match[right] == 0 || find(match[right])){
match[right] = left;
return true;
}
}
return false;
}
}