二分图--二分图的几种模型

二分图最大匹配

二分图匹配:每个左部点最多与一个右部点相连,每个右部点最多与一个左部点相连

算法流程:

如果后来的和以前的发生矛盾,则以前的优先退让。

如果以前的退让之后没有点与之相连,则以前的拒绝退让,新来的去寻找下一个匹配。

如果新来的谁也匹配不上,就匹配不上吧:

学会了二分图最大匹配后,另外几种模型也可求解。

最小点覆盖

最小点覆盖:选取最少的点,使得所有的点与至少一个被选取点距离不超过1,或选取最少的点,使得所有边都至少与一个被选取点相连

方法:最小点覆盖=最大匹配

最大独立集

最大独立集:选取最多的点,使得其中任意两点互不相达

方法:最大独立集 = 点总数 - 最大匹配

最小边覆盖

最小边覆盖:选取最少的边使得所有的点被至少一条边覆盖

方法:最小边覆盖 = 总点数 - 最大匹配

代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=5e4+10;
int read(){
	int x=1,a=0;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') x=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){a=a*10+ch-'0';ch=getchar();}
	return x*a;
}
struct node{
	int to,next;
}ed[maxn];
int head[maxn],tot;
int matc[maxn],vis[maxn];
void add(int u,int to){
	ed[++tot].to=to;
	ed[tot].next=head[u];
	head[u]=tot;
}
int n,m,e;
bool dfs(int x){
	for(int i = head[x];i;i=ed[i].next){
		int to=ed[i].to;
		if (vis[to]) continue; vis[to]=1;
		if (matc[to]==0||dfs(matc[to])){
			matc[to]=x; 
			return true;
		}
	}
	return false;
}
int main(){
	n=read(),m=read(),e=read();
	for (int i = 1;i <= e;i++){
		int u,v;
		u=read(),v=read();
		add(u,v);
	}
	int ans=0;
	for(int i = 1;i <= n;i++){
		memset(vis,0,sizeof(vis));
		if (dfs(i)) ans++;
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2020-10-20 07:36  小又又  阅读(208)  评论(0编辑  收藏  举报