洛谷 P1894 [USACO4.2] 完美的牛栏The Perfect Stall

题目来源于:洛谷

题目本质:二分图

虽然本质上是二分图,但我好像没用,我直接食用的匈牙利算法,直接出来了。

(匈牙利算法不太明白的,详见趣写算法系列之--匈牙利算法_匈牙利算法基本原理-CSDN博客)

解题思路:
把牛和牛栏分成两个集合 每只牛可以匹配至少一个牛栏。

先遍历牛,把第一只牛匹配上第一个牛栏,然后再对第二只牛进行匹配。

如果第二只牛可以匹配到第一个牛栏,而这时第一只牛又有另一种匹配选择,那么第二只牛就匹配上第一个牛栏,第一只牛去找另一个牛栏来匹配,以此类推。 

代码如下:
 

#include<bits/stdc++.h>
using namespace std;
const int N=10005;
int n,m,t,ans=0,x_[N],y_[N];
bool flag[1005][1005],vis[N];
//flag记录每只牛可以匹配的牛栏
inline bool find(int x){
	for(int i=1;i<=m;i++){
		if(flag[x][i]&&!vis[i]){//如果这只牛能匹配上这个牛栏并且这个牛栏没有被其他牛占据
			vis[i]=true;
			if(y_[i]==-1||find(y_[i]))
            //如果这个牛栏没有被占据或者这个牛栏可以腾出来,即原来占据的牛可以找到另一个牛栏
            //这里使用递归实现匹配
			{
				x_[i]=i;
				y_[i]=x;
				return true;
			}
		}
	}
	return false;
}
inline void match(){
	memset(x_,-1,sizeof(x_));
	memset(y_,-1,sizeof(y_));
	for(int i=1;i<=n;i++){
		memset(vis,false,sizeof(vis));
		ans+=find(i);
  	  //如果匹配成功,find(i)的值为真,即为1
	}
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>t;
		for(int j=1;j<=t;j++){
			int x;
			cin>>x;
			flag[i][x]=true;
  			//第i只牛可以匹配第x个牛栏
		}
	}
	match();
	cout<<ans;  
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值