J - Ginger的牧场(二分图,匈牙利算法)

题目链接:J - Ginger的牧场 | SDUT OnlineJudge

题目:

Ginger 是个牧场主,他一共养了 n 头牛,他的牧场里有 m 头母牛和 n−m 头小牛。有一天 GingerGinger 发现有的小牛被好多头母牛喂养,有的小牛却没有母牛喂养。他想出来了一个办法:尽可能多地把母牛和小牛一一配对,使得被母牛喂养的小牛尽可能多。他想问你能得到喂养的小牛最多有多少头?

Input

输入的第一行包含三个正整数,分别代表母牛的个数 m 、牛的总数 n 和被喂养的关系数 q

Output

接下来 q 行,每行有两个字符串 u,v,代表母牛 u 可以喂养小牛 v

思路:用map把字符串映射成数,通过匈牙利算法去计算出最大匹配量

代码:

#include<bits/stdc++.h>
#define int long long
#include<string.h>
using namespace std;
const int N=7e3+5;
int n,k,m,a[N],b,x,y;
vector<int>g[105];
int cnt[105],vis[105];
int match[105];
map<string,int>mp;
set<int>s;
int find(int u){//递归
	for(auto v:g[u]){//遍历每只小牛
		if(!vis[v]){
			vis[v]=1;//已经被查询过了
			if(!match[v]||find(match[v])){//如果小牛未被其他牛匹配,或者与他匹配的母牛重新能找到一个新的小牛
				match[v]=u;//将母牛与小牛匹配
				return 1;
			}
		}
	}
	return 0;
}
void solve(){
	int q;
	cin>>m>>n>>q;
	int d=0,dd=0;

	while(q--){
		string u,v;
		cin>>u>>v;
		getchar();
		if(mp[u]==0){//映射
			mp[u]=++d;
		}
		if(mp[v]==0){
			mp[v]=++d;
		}
		s.insert(mp[u]);//存储母牛的编号
		g[mp[u]].push_back(mp[v]);//存储每只母牛可以喂哪些小牛
	}
	for(auto u:s){//遍历每只母牛,这是一个不断更新所匹配的小牛的过程
		fill(vis,vis+103,0);//令所有子牛都假设没配对
		if(find(u))k++;
	}
	cout<<k;
}
signed main()
{
	std::ios::sync_with_stdio(false);
	cin.tie(0); 
	cout.tie(0);
	int T;
//	cin>>T;
	T=1;
	while(T--){
		solve();
	}
}

匈牙利算法讲解比较好的链接:AcWing 861. 二分图的最大匹配----图解--$\color{red}{海绵宝宝来喽}$(转) - AcWing

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值