看了别人解释了什么是二分图后,才想起来原来离散数学中讲的 Bipartite Graph 就是它。
这道题是最大配对问题,用到了匈牙利算法。其实理解了就不难,主要有三步:
<1> 读取数据,并用一种数据结构表示(邻接矩阵,邻接表都行)
<2> 取某一边的集合,对每一个点都进行dfs
<3> dfs 的过程也就是寻找所谓的可增广路的过程
#include<iostream>
#include<cstring>
using namespace std;
bool map[210][210];
bool visit[210];
int match[210];
int N, M;
int dfs(int x){
for(int i = 1; i <= M; i++){
if(map[x][i] && !visit[i]){
visit[i] = true;
if(match[i] == 0 || dfs(match[i])){
match[i] = x;
return true;
}
}
}
return false;
}
int hungary(){
int result = 0;
for(int i = 1; i <= N; i++){
memset(visit, false, sizeof(visit));
if(dfs(i))
result++;
}
return result;
}
int main(){
while(cin >> N >> M){
memset(map, false, sizeof(map));
memset(match, 0, sizeof(match));
for(int i = 1; i <= N; i++){
int num;
cin >> num;
for(int j = 0; j < num; j++){
int x;
cin >> x;
map[i][x] = true;
}
}
cout << hungary() << endl;
}
}