二分图匹配

所谓的二分图的最大匹配是指在二分图中选择出最多的边数,且选择的边不共点。
1.首先选择一个没有匹配的点x,选择x的任意一条边(x,y),如果y也没有匹配,那么就选(x,y),如果y已经被匹配了, 那么就让已经匹配y的点z去尝试找一个新的匹配;如果x和y能够匹配成功,那么匹配数就加1。
2.如果x和y没有匹配成功,那么再尝试x的另一条边;
3.对于所有的点,重复1,2两步
代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn=2000+10;
int pp[maxn],n,m,e,ans;
bool d[maxn][maxn],b[maxn];
int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=(x<<1)+(x<<3)+(ch^48);
		ch=getchar();
	}
	return x*f;
}
bool dfs(int k){
	for(int i=1;i<=n;i++)
		if(d[k][i]&&!b[i]){
			b[i]=true;
			if(!pp[i]||dfs(pp[i])){
				pp[i]=k;
				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();
		if(u>n||v>m)
		    continue;
		d[u][v]=true;
	}
	for(int i=1;i<=m;i++){
		memset(b,0,sizeof(b));
		if(dfs(i))	
			ans++;
	}
	printf("%d",ans);
	return 0;
}

二分图的多重匹配:就是点i可以用ki次【最大流】
二分图的带权匹配:边带有权值,KM,费用流
二分图的最小点(权)覆盖:
对于一张二分图G(V,E),从V中选择一个子集S,使得图中所有的边至少有1个端点落在S中,这样的最小的点数的S就称之为G的最小点覆盖。
最小点覆盖==最大匹配

二分图的最大独立集:
对于一张无向图G(V,E ),选出一个V的子集S,使得S中任意两点之间都没有边,且S是最大的这样的子集。

如何求二分图的最大独立集:
最大独立集点的数量==N-二分图的最大匹配
证明:要使得独立集越大,那么删掉的点就要越少,同时还要保证删掉的点覆盖到所有的边,所以删掉的应该是最小点覆盖

最小路径点覆盖:对于一张有向无环图(DAG),用尽量少的简单路径(没有重复经过点的)覆盖所有的点。每一个点只能恰好被覆盖一次。这样的问题就是有向无环图的最小路径点覆盖。
如何求:首先,将原图中的每一个点
x拆成x和(x+n),这样就可以分成1-n和n+1到2n两个点集
然后,在原图中x->y的这条边,转化成x->(y+n),得到一张新图G’
原图的最小路径点覆盖==N-G’的最大匹配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值