原题链接
①. 题目
②. 思路
- 匹配:在图论中,一个「匹配」是一个边的集合,其中任意两条边都没有公共顶点。
- 最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
- 完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。
- 交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。
- 增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替 路称为增广路
③. 学习点
匈牙利算法
④. 代码实现
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
static int N=510,M=100010;
static int[] h=new int[M];
static int[] e=new int[M];
static int[] ne=new int[M];
static int idx;
static int[] match=new int[N];
static boolean[] st=new boolean[N];
static void add(int u,int v) {
e[idx]=v;
ne[idx]=h[u];
h[u]=idx++;
}
static boolean find(int u) {
for(int i=h[u];i!=-1;i=ne[i]) {
int j=e[i];
if(!st[j]) {
st[j]=true;
if(match[j]==0||find(match[j])) {
match[j]=u;
return true;
}
}
}
return false;
}
public static void main(String[] args) throws IOException {
Arrays.fill(h,-1);
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
String[] arr=in.readLine().split(" ");
int n1=Integer.parseInt(arr[0]);
int n2=Integer.parseInt(arr[1]);
int m=Integer.parseInt(arr[2]);
while(m-->0){
String[] num=in.readLine().split(" ");
int u=Integer.parseInt(num[0]);
int v=Integer.parseInt(num[1]);
add(u,v);
}
int res=0;
for(int i=1;i<=n1;i++) {
Arrays.fill(st, false);
if(find(i)) {
res++;
}
}
System.out.println(res);
}
}