문제: icpc.me/11377
사람과 일을 1:1로 매칭할 때 최대매칭을 구하는데 일을 여러번 할 수 있는 직원의 수 K가 별도로 주어질 때의 최대매칭을 구하는 문제이다.
이분 매칭에서의 최대매칭을 구하는데 우리는 중간에 BRIDGE를 둬서 소스에서 BRIDGE로 K만큼 흘려준 뒤 BRIDGE에서 이분 그래프의 좌측 으로 1씩 capacity를 주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | #include <cstdio> #include <algorithm> #include <vector> #include <queue> #include <cstring> #define MAX_N 1000 #define S 2003 #define E 2004 #define BRIDGE 2005 #define INF 987654321 using namespace std; int work[2 * MAX_N + 10], level[2 * MAX_N + 10], n, m, k, x, y, r; struct Edge { int v, cap, rev; Edge(int v, int cap, int rev) : v(v), cap(cap), rev(rev) {} }; vector<vector<Edge>> vt; void addEdge(int s, int e, int c) { vt[s].emplace_back(e, c, vt[e].size()); vt[e].emplace_back(s, 0, vt[s].size() - 1); } bool bfs() { memset(level, -1, sizeof(level)); queue<int> qu; qu.push(S); level[S] = 0; while (qu.size()) { int here = qu.front(); qu.pop(); for (auto i : vt[here]) { int there = i.v; int cap = i.cap; if (level[there] == -1 && cap > 0) { level[there] = level[here] + 1; qu.push(there); } } } return level[E] != -1; } int dfs(int here, int crtcap) { if (here == E)return crtcap; for (int &i = work[here]; i < vt[here].size(); i++) { int there = vt[here][i].v; int cap = vt[here][i].cap; if (level[here] + 1 == level[there] && cap>0) { int c = dfs(there, min(crtcap, cap)); if (c > 0) { vt[here][i].cap -= c; vt[there][vt[here][i].rev].cap += c; return c; } } } return 0; } int main() { scanf("%d%d%d", &n, &m, &k); vt.resize(MAX_N * 2 + 10); addEdge(S, BRIDGE, k); for (int i = 1; i <= n; i++) { scanf("%d", &x); while (x--) { scanf("%d", &y); addEdge(i, y + n, 1); } addEdge(S, i, 1); addEdge(BRIDGE, i, 1); } for (int i = 1; i <= m; i++) addEdge(n + i, E, 1); while (bfs()) { memset(work, 0, sizeof(work)); while (1) { int flow = dfs(S, INF); if (!flow)break; r += flow; } } printf("%d\n", r); return 0; } | cs |
'알고리즘 관련 > BOJ' 카테고리의 다른 글
BOJ)1671 상어의 저녁식사 (0) | 2017.02.16 |
---|---|
BOJ)1867 돌멩이 제거 (0) | 2017.02.16 |
BOJ)11376 열혈강호2 (0) | 2017.02.15 |
BOJ)10090 Counting Inversions (0) | 2017.02.15 |
BOJ)2262 토너먼트 만들기 (0) | 2017.02.15 |