【总结】 二分图的各种算法
前言
为了联赛复习,我又开始写各种总结了,虽然好像联赛不考二分图。。。QwQ
二分图匹配
显然直接能选就选,不能选就换就好了。(匈牙利算法的精髓!!!)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
using namespace std;
const int N=400010;
int n,m,e,used[N],to[N<<1],nxt[N<<1],front[N],cnt,b[N];
bool dfs(int u){
for(int i=front[u];i;i=nxt[i]){
int v=to[i];
if(!used[v]){
used[v]=1;
if(!b[v] || dfs(b[v])){
b[v]=u;return true;
}
}
}
return false;
}
void Add(int u,int v){
to[++cnt]=v;nxt[cnt]=front[u];front[u]=cnt;
}
int main(){
scanf("%d%d%d",&n,&m,&e);
for(int i=1;i<=e;i++){
int a,b;scanf("%d%d",&a,&b);
if(a>n || b>m)continue;
Add(a,b+n);
}
int ans=0;
for(int i=1;i<=n;i++){
memset(used,0,sizeof(used));
if(dfs(i))ans++;
}
printf("%d\n",ans);
return 0;
}
二分图最佳匹配
直接在原图上面跑一个最大费用最大流就好了。
二分图建图基本模型
二分图构造
一般性二分图不会考什么裸题,那么如何构造这个东西呢?
网格图点覆盖,选择最少的点覆盖每一行和每一列。把行和列看作点,原来的点看作边,求二分图最小边覆盖即可。
DAG拆点求最大匹配,详情参考餐巾计划问题