UVA11419 SAM I AM (二分图最小覆盖)

二分图中

最小覆盖数=最大匹配数

证明:http://blog.csdn.net/qq_30802053/article/details/77482209

用匈牙利算法求最大匹配数;

下面再求输出方案:

上面的连接讲了求最小覆盖数的选择点,选择Right[i]==-1(就是找非匹配边)的点进行match(i),然后选S集合中未标记的和T集合中标记了的就是输出方案。

代码:

#include<iostream>
#include<cstring>
using namespace std;
const int maxn=101;
int S[maxn],T[maxn],Left[maxn],Right[maxn];
int link[maxn][maxn],n,m;
bool match(int i){
	S[i]=1;
	for(int j=1;j<=m;j++)if(!T[j]&&link[i][j]){
		T[j]=true;
		if(!Left[j]||match(Left[j])){
			Left[j]=i;
			Right[i]=j;
			return true;
		}
	}
	return false ;
}
void Maxmatch(){
	memset(Left,0,sizeof(Left));
	memset(Right,-1,sizeof(Right));
	int ans=0;
	for(int i=1;i<=n;i++){
		memset(T,0,sizeof(T));
		memset(S,0,sizeof(S));
		if(match(i))ans++;
	}
	cout<<ans<<" ";
	memset(T,0,sizeof(T));
	memset(S,0,sizeof(S));
	
	for(int i=1;i<=n;i++){
		if(Right[i]==-1){
			match(i);//cout<<i<<" ";
		}
	}
	for(int u=1;u<=n;u++)if(!S[u])printf("r%d ",u);
	for(int v=1;v<=m;v++)if(T[v])printf("c%d ",v);
}
int main(){
	freopen("in.txt","r",stdin);
	cin>>n>>m;
	int t;cin>>t;
	while(t--){
		int x,y;
		cin>>x>>y;
		link[x][y]=1;
	}
	Maxmatch();
} 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值