AcWing 861. 二分图的最大匹配
原题链接
简单
作者:
Acvv_scl
,
2021-03-10 23:12:12
,
所有人可见
,
阅读 264
核心点
- 每一个汉子都要 尝试遍历每一个妹子(当然从自己的好感数组 也就是邻接表 链表里面遍历) st数组要清空
- 尝试 勾引 妹子之后 要标志位 st[i]设置为true 防止 重复访问同一个妹子
- 如果妹子没有被别的汉子勾引走,那么 就跟这个妹子 匹配上;
- 如果妹子 已经被别的汉子 勾引走了,那么 尝试下 挖墙脚 是否能成功;成功返回true;否则继续;
import java.util.*;
public class Main{
static int N=510;
static int M=100010;
static int n1;
static int n2;
static int m;
static int h[]=new int[N];
static int []e=new int[M];
static int []ne=new int[M];
static int index;
//对每个左侧的节点来说 右侧的节点 他有没有区匹配过?
static boolean[]st=new boolean[N];
//右侧的节点 也就是 妹子 被哪个汉子选中了?
static int []match=new int[N];
static void add(int a,int b){
e[index]=b;ne[index]=h[a];h[a]=index++;
}
//看下 u节点 这个汉子 能不能匹配到妹子
static boolean find(int u){
//从他的有好感的妹子中 开始 找(就是邻接表的链)
for(int i=h[u];i!=-1;i=ne[i]){
int j=e[i];
//如果他之前没有勾引过这个妹子;就尝试去勾引
if(!st[j]){
//注意一定要更新 这个妹子 已经被u节点的汉子 查询过
st[j]=true;
//如果这个妹子没有被别人勾引走,或者 就算勾走了还能挖墙脚成功
if(match[j]==0||find(match[j])){
match[j]=u;
return true;
}
}
}
return false;
}
public static void main(String[]args){
Arrays.fill(h,-1);
Scanner sc=new Scanner(System.in);
n1=sc.nextInt();
n2=sc.nextInt();
m=sc.nextInt();
while(m-->0){
int a=sc.nextInt();
int b=sc.nextInt();
add(a,b);
}
int res=0;
for(int i=1;i<=n1;i++){
//每一个汉子 都要遍历尝试勾引 每一个妹子;所以要清空数组
Arrays.fill(st,false);
if(find(i))res++;
}
System.out.println(res);
}
}