题目链接: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