참고 블로그
Network Flow를 이용해 할 수 있는 대표적인 알고리즘이다. 어떤 A집단이 B집단을 선택할 때 가장 많은 연결이 발생하도록 하는 알고리즘이다.
예를 들어 아래와 같은 연결 관계가 있을 때

이를 Network Flow구조로 바꿀 수 있다.

이렇게 Network Flow구조로 생각하면 위에서 말한 최대 연결가능 횟수는 Maximum Flow문제가 되어버린다. 따라서 Edmonds-karp같은 Maximum Flow알고리즘을 적용시킬 수 있다.
Edmonds-karp의 시간복잡도는 $O(V*E^2)$인데 DFS를 이용하여 이분매칭 한해서 더 빠르게 만들 수가 있다.
Parent와 visit을 저장할 배열이 필요하다.
최대 연결 수는 cnt를 통해 확인할 수 있고, 노드의 연결은 parent를 보면 된다.
전형적인 문제이다.
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>
using namespace std;
typedef long long LL;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
#define MAX 101
int n, m;
int a, b;
vi net[MAX];
bool visit[MAX];
int parent[MAX];
int cnt;
bool dfs(int cur) {
for (auto next : net[cur]) {
if (visit[next]) continue;
visit[next] = true;
if (!parent[next] || dfs(parent[next])) {
parent[next] = cur;
return true;
}
}
return false;
}
void solve() {
cin >> n >> m;
for (int i = 0; i < m; i++) {
cin >> a >> b;
net[a].push_back(b);
}
for (int i = 1; i <= n; i++) {
memset(visit, false, sizeof(visit));
if (dfs(i)) cnt++;
}
cout << cnt << '\\n';
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
solve();
}