算法设计与分析 6.1 结对编程
★题目描述
现在有n个代码手和m个观察者,只有相互熟悉的代码手和观察者才能进行良好的结对编程。
请问怎样搭配可以有最多的结对编程组合
★输入格式
输入的第一行三个数字n,m和k(1<=n,m<=100,1<=k<=n*m),表示代码手人数、观察者人数和熟识的关系数目。
接下来k行每行两个数字a(1<=a<=n),b(1<=b<=m)代表第a位代码手与第b位观察者相互熟识。
★输出格式
输出一个整数表示最多的结对编程组合。
★样例输入
2 2 2
1 1
2 2
★样例输出
2
★提示
无
★参考代码
/*
用邻接表记录关系
套一个二分最大匹配模板
n个代码手分到A子集中
m个观察者分到B子集中
*/
#include<bits/stdc++.h>
using namespace std;
int Match[100+5]; //记录的是B子集(观察者)是否已经匹配了
int Visit[100+5]; //记录的是B子集(观察者)是否已经问过了
int H[100+5]; //记录的是A子集(代码手)熟识的观察者
struct Edge{
int end,nxt;
}E[10000+5];
int idx=0;
void AddEdge(int u, int v){
idx++;
E[idx].end = v;
E[idx].nxt = H[u];
H[u] = idx;
}
int find(int x){
for(int i=H[x]; i!=0; i=E[i].nxt){
int e=E[i].end;
if(Visit[e]==0){
Visit[e]=1;
if(Match[e]==0 || find(Match[e])){
Match[e]=x;
return 1;
}
}
}
return 0;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
int n,m,k;
cin>>n>>m>>k;
int u,v;
while(k--){
cin>>u>>v;
AddEdge(u,v);
}
int res=0;
memset(Match, 0, sizeof(Match));
for(int i=1; i<=n; ++i){
memset(Visit, 0, sizeof(Visit));
res += find(i);
}
cout<<res<<endl;
return 0;
}