2020-1ํ•™๊ธฐ, ๋Œ€ํ•™์—์„œ โ€˜์•Œ๊ณ ๋ฆฌ์ฆ˜โ€™ ์ˆ˜์—…์„ ๋“ฃ๊ณ  ๊ณต๋ถ€ํ•œ ๋ฐ”๋ฅผ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. ์ง€์ ์€ ์–ธ์ œ๋‚˜ ํ™˜์˜์ž…๋‹ˆ๋‹ค :)

10 minute read

2020-1ํ•™๊ธฐ, ๋Œ€ํ•™์—์„œ โ€˜์•Œ๊ณ ๋ฆฌ์ฆ˜โ€™ ์ˆ˜์—…์„ ๋“ฃ๊ณ  ๊ณต๋ถ€ํ•œ ๋ฐ”๋ฅผ ์ •๋ฆฌํ•œ ๊ธ€์ž…๋‹ˆ๋‹ค. ์ง€์ ์€ ์–ธ์ œ๋‚˜ ํ™˜์˜์ž…๋‹ˆ๋‹ค :)

์ด๋ฒˆ ํฌ์ŠคํŠธ๋Š” Network Flow ํฌ์ŠคํŠธ์˜ ํ›„์† ํฌ์ŠคํŠธ์ž…๋‹ˆ๋‹ค. Network Flow ๋ฌธ์ œ์˜ ํ•ต์‹ฌ์ด ๋˜๋Š” ์ •๋ฆฌ์ธ <Max-Flow Min-Cut Theorem>์— ๋Œ€ํ•ด ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์ด์ „ ํฌ์ŠคํŠธ๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”! ๐Ÿ˜‰

์ด๋ฒˆ ํฌ์ŠคํŠธ์˜ ์ฝ”๋“œ๋Š” ๋ฐฑ์ค€ 6086๋ฒˆ: ์ตœ๋Œ€ ์œ ๋Ÿ‰ ๋ฌธ์ œ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค ๐Ÿ‘จโ€๐Ÿ’ป


Network Flow ํฌ์ŠคํŠธ์—์„œ ์–ด๋–ป๊ฒŒ Max Flow๋ฅผ ๊ตฌํ• ์ง€ <Max-Flow Min-Cut Theorem>์„ ํ†ตํ•ด ์‚ดํŽด๋ณด์•˜๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” Residual Graph๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ•ด๋‹น ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ง์ ‘ ๊ตฌํ˜„ํ•ด๋ณธ๋‹ค.


Ford-Fulkerson Algorithm

์‚ฌ์‹ค Network Flow ํฌ์ŠคํŠธ์—์„œ ์„ค๋ช…ํ•œ Max-Flow๋ฅผ ์ฐพ๋Š” ๋ฐฉ๋ฒ•์„ ์ฝ”๋“œ๋กœ ๊ตฌํ˜„ํ•œ ๊ฒƒ์— ๋ถˆ๊ณผํ•˜๋‹ค. ํฐ ๋ฒ”์ฃผ๋กœ ๋ดค์„ ๋•Œ๋Š” Brute Force Algorithm์— ์†ํ•œ๋‹ค.

1. source์—์„œ sink๋กœ ๊ฐ€๋Š” ์œ ๋Ÿ‰์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ $p$๋ฅผ ํ•˜๋‚˜ ์ฐพ๋Š”๋‹ค. DFS ๋˜๋Š” BFS๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

2. ์ฐพ์•„๋‚ธ ๊ฒฝ๋กœ $p$๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ํ•œ์˜ ์œ ๋Ÿ‰์„ ๊ตฌํ•œ๋‹ค. ์ตœ๋Œ€ํ•œ์˜ ์œ ๋Ÿ‰์€ ๊ฒฝ๋กœ $p$๋ฅผ ํƒ์ƒ‰(traversal)ํ•˜๋ฉฐ ๊ฐ€์žฅ ์ž‘์€ ๋‚จ์€ capacity๊ฐ€ ๋œ๋‹ค.

3. ์ฐพ์•„๋‚ธ ๊ฒฝ๋กœ $p$์— ์ตœ๋Œ€ ์œ ๋Ÿ‰์„ ์‹ค์ œ๋กœ ํ˜๋ ค๋ณด๋‚ธ๋‹ค. ์ด ๊ณผ์ •์—์„œ ์ˆœ๋ฐฉํ–ฅ์€ ์œ ๋Ÿ‰์„ ์ถ”๊ฐ€ํ•˜๊ณ , ์—ญ๋ฐฉํ–ฅ์€ ์œ ๋Ÿ‰์€ ๋บ€๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์ฐพ์•„๋‚ธ ๊ฒฝ๋กœ $p$๊ฐ€ $a \rightarrow b \rightarrow c$๋ผ๋ฉด,

// ์ˆœ๋ฐฉํ–ฅ
f(a, b) += flow
f(b, c) += flow

// ์—ญ๋ฐฉํ–ฅ
f(b, a) -= flow
f(c, b) -= flow

์ฃผ๋ชฉํ•  ์ ์€ [3.] ๊ณผ์ •์—์„œ ์—ญ๋ฐฉํ–ฅ์„ ์ฒ˜๋ฆฌํ•  ๋•Œ์ธ๋ฐ, ๋งŒ์•ฝ $f(b, a) = 0$์ด์—ˆ๋‹ค๋ฉด $f(b, a) < 0$๋กœ ์Œ์ˆ˜๊ฐ€ ๋œ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด๋Ÿฐ ์Œ์ˆ˜ ์œ ๋Ÿ‰์„ ํ˜๋ ค๋ณด๋‚ด๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•œ๋ฐ, $f(b, a)$์˜ capacity๋Š” $c(b, a) = 0$์ด๋ฏ€๋กœ ๊ฒฐ๊ตญ $f(b, a) < 0 = c(b, a)$๋กœ ์œ ๋Ÿ‰์— ๋Œ€ํ•œ ๋ฒ•์น™์„ ์ „ํ˜€ ๊นจ๋œจ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค!

์ฝ”๋“œ๋กœ ์ž‘์„ฑํ•˜๊ธฐ ์ „์— ์†์œผ๋กœ ์ด ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ๋”ฐ๋ผ๊ฐ€๋ณด์ž. ์ด ๋ถ€๋ถ„์€ ์ข‹์€ ์ž๋ฃŒ๊ฐ€ ์žˆ์–ด์„œ ํ•ด๋‹น ์ž๋ฃŒ๋กœ ๋Œ€์ฒดํ•˜๊ฒ ๋‹ค. ๐Ÿ™ ์†์œผ๋กœ ํ‘ธ๋Š” Ford-Fulkerson Algorithm


์ด์ œ ์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด์ž.

โœจ Tip: ์ด ๋ฌธ์ œ์˜ ๊ฒฝ์šฐ ๊ทธ๋ž˜ํ”„๋ฅผ Adjacency List ๋ณด๋‹ค๋Š” Adjacency Matrix๋กœ ํ‘œํ˜„ํ•˜๋Š”๊ฒŒ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์งœ๊ธฐ ํ›จ์”ฌ ํŽธํ•ด์ง„๋‹ค! ๐Ÿ˜‰

๋จผ์ € ๋ฌธ์ œ์˜ ์ž…๋ ฅ์„ ๋ณด๋ฉด, ๋…ธ๋“œ๊ฐ€ Alphabet ๋Œ€์†Œ๋ฌธ์ž๋กœ ๋“ค์–ด์˜จ๋‹ค. ๋ณธ์ธ์€ ์†Œ๋ฌธ์ž๋กœ๋„ ๋“ค์–ด์˜จ๋‹ค๋Š” ๊ฑธ ๋‚˜์ค‘์— ๊นจ๋‹ฌ์•˜๋‹ค ๐Ÿ˜ฑ ์ž…๋ ฅ์„ ์ •๊ทœํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„  'A'๋กœ ๋นผ์ฃผ๋ฉด ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ๋…ธ๋“œ๋Š” [A-Z]: [0, 26], [a-z]: [32, 57]์˜ ๋ฒˆํ˜ธ๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค.

์šฐ๋ฆฌ๋Š” int capacity[][]๋ผ๋Š” ๋ฐฐ์—ด์— ํŒŒ์ดํ”„์— ํ๋ฅผ ์ˆ˜ ์žˆ๋Š” ์œ ๋Ÿ‰์˜ capacity๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. ๊ทธ๋ž˜์„œ ์ž…๋ ฅ์„ ํ†ตํ•ด Graph๋ฅผ ๊ตฌ์ถ•ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

#define MAX 80

int capacity[MAX][MAX];

for (int i = 0; i < N; i++) {
  char s, e;
  int c;
  cin >> s >> e >> c;
  capacity[s - 'A'][e - 'A'] += c;
  capacity[e - 'A'][s - 'A'] += c;
}

์ด์ œ ์ค€๋น„๋Š” ๋๋‚ฌ๊ณ , ๋ณธ๊ฒฉ์ ์œผ๋กœ <\Ford-Fulkerson Algorithm>์„ ๊ตฌํ˜„ํ•ด๋ณด์ž.

long long FordFulkerson(int source, int sink) {
  long long ret = 0;

  // find path and update residual graph
  while (1) {
    ...
    // dfs
    while (!s.empty()) {
      ...
    }

    // escape: no possible path
    if (Prev[sink] == -1) break;

    // find possible max-flow

    // flow the max-flow

    total_flow += flow;
  }

  return total_flow;
}

๋จผ์ € dfs ๊ตฌํ˜„ ๋ถ€๋ถ„์„ ์‚ดํŽด๋ณด์ž.

  int Prev[MAX];
  fill(Prev, Prev + MAX, -1);
  Prev[source] = source;

  stack<int> s;
  s.push(source);

  // dfs
  while (!s.empty()) {
    int curr = s.top();
    s.pop();

    if(curr == sink) break;

    for (int i = 0; i < MAX; i++) {
      if (Prev[i] == -1 && capacity[curr][i] > 0) {
        s.push(i);
        Prev[i] = curr;
      }
    }
  }

  // escape: no possible path
  if (Prev[sink] == -1) break;

stack<int>๋ฅผ ์ด์šฉํ•ด DFS๋ฅผ ๊ตฌํ˜„ํ–ˆ์œผ๋ฉฐ, Prev[]์— path history๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. ๋งŒ์•ฝ sink์— ๋„๋‹ฌํ–ˆ๋‹ค๋ฉด, ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰์„ ์ข…๋ฃŒํ•œ๋‹ค. ๋งŒ์•ฝ sink์— ๋„๋‹ฌํ•˜์ง€ ๋ชป ํ–ˆ๋‹ค๋ฉด ์ฆ‰ sink๋กœ ๊ฐ€๋Š” ๊ฒฝ๋กœ๋ฅผ ์ฐพ์ง€ ๋ชป ํ–ˆ๋‹ค๋ฉด, Prev[sink]์˜ ๊ฐ’์ด ๊ฐฑ์‹ ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ Prev[sink] == -1์ด ๋œ๋‹ค. ์ด ๊ฒฝ์šฐ๋ผ๋ฉด, ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ข…๋ฃŒํ•œ๋‹ค.

์‚ฌ์‹ค ์œ„์˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ตธํผ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

  int Prev[MAX];
  fill(Prev, Prev + MAX, -1);
  Prev[source] = source;

  stack<int> s;
  s.push(source);

  // dfs
  while (!s.empty()) {
    int curr = s.top();
    s.pop();

    for (int i = 0; i < MAX; i++) {
      if (Prev[i] == -1 && capacity[curr][i] > 0) {
        s.push(i);
        Prev[i] = curr;

        if (i == sink) break;
      }
    }

    if (Prev[sink] != -1) break;
  }

  // escape: no possible path
  if (Prev[sink] == -1) break;

๋‹ค๋งŒ ์ฒ˜์Œ์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•ด๋„ ํ†ต๊ณผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํฌ๊ฒŒ ์‹ ๊ฒฝ์“ฐ์ง€๋Š” ๋ง์ž.


๋‹ค์Œ์€ ์ฐพ์€ ๊ฒฝ๋กœ๋ฅผ ์ด์šฉํ•ด ๊ทธ๋ž˜ํ”„์— ํ˜๋ฆด ์œ ๋Ÿ‰์„ ์ฐพ์•„์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์€ ์•„๋ž˜์˜ ์ฝ”๋“œ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

  // find possible max-flow
  int flow = INT_MAX;
  for (int v = sink; v != source; v = Prev[v]) {
    flow = min(flow, capacity[Prev[v]][v]);
  }

for (int v = sink; v != source; v = Prev[v]) ํŒจํ„ด์€ ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰์—์„œ ๊ฒฝ๋กœ๋ฅผ ์žฌ๊ตฌ์„ฑ ํ•  ๋•Œ ์ž์ฃผ ์“ฐ๋Š” ํ…Œํฌ๋‹‰์ด๋ฏ€๋กœ ์ˆ™์ง€ ํ•˜๋„๋ก ํ•˜์ž. ๐Ÿ™Œ


๋‹ค์Œ์€ ๊ฒฝ๋กœ์— ์œ ๋Ÿ‰ flow๋ฅผ ํ๋ฅด๊ฒŒ ํ•˜๋Š” ์ž‘์—…์ด๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒฝ๋กœ๋ฅผ ์žฌํƒ์ƒ‰ํ•˜๋ฉฐ ์œ ๋Ÿ‰์„ ํ˜๋ ค๋ณด๋‚ด๋ฉด ๋œ๋‹ค.

  // flow the max-flow
  for (int v = sink; v != source; v = Prev[v]) {
    capacity[Prev[v]][v] -= flow;
    capacity[v][Prev[v]] += flow;
  }

  // update total flow!
  total_flow += flow;

์ด๋•Œ, ์—ญ๋ฐฉํ–ฅ์œผ๋กœ๋Š” capacity๊ฐ€ ๋Š˜์–ด๋‚œ๋‹ค๋Š” ์‚ฌ์‹ค์— ์œ ์˜ํ•˜์ž.


์‹œ๊ฐ„ ๋ณต์žก๋„

์œ„์˜ ๊ทธ๋ฆผ์€ <Ford-Fulkerson Algorithm>์—์„œ ์ตœ์•…์˜ ์ƒํ™ฉ์˜ ์˜ˆ์‹œ์ด๋‹ค. DFS๋กœ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ๋งค ์‹œํ–‰๋งˆ๋‹ค ์šฉ๋Ÿ‰ 1์˜ ๊ฐ€์šด๋ฐ ๊ฐ„์„ ์„ ์ง€๋‚œ๋‹ค๊ณ  ํ•˜์ž. ๊ทธ๋Ÿฌ๋ฉด ์šฉ๋Ÿ‰ 1,000์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด 1,000์€ iteration์„ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ด๊ฒƒ์€ DFS๋กœ ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” <Ford-Fulkerson Algorithm>์˜ ํ•œ๊ณ„์ด๋‹ค ๐Ÿ˜ฅ

์œ„์˜ ์ƒํ™ฉ์„ ๋ฐ”ํƒ•์œผ๋กœ <Ford-Fulkerson Algorithm>์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ์œ ๋„ํ•ด๋ณด์ž. ๊ทธ๋ž˜ํ”„ $G_f$์—์„œ ์ตœ๋Œ€ ์šฉ๋Ÿ‰์ด $f_{\max}$๋ผ๊ณ  ํ•˜์ž. ํ•œ๋ฒˆ์˜ DFS ํƒ์ƒ‰์œผ๋กœ ํ˜๋ฆด ์ˆ˜ ์žˆ๋Š” ์œ ๋Ÿ‰์˜ ์ตœ์†Ÿ๊ฐ’์€ 1์ด๋ฏ€๋กœ ์ด $f_{\max}$๋ฒˆ์˜ DFS๋ฅผ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ด๋•Œ, DFS์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ $O(V + E)$์ด๋ฏ€๋กœ, <Ford-Fulkerson Algorithm>์€ $O((V + E) f_{\max})$ ๋งŒํผ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค! ๋งŒ์•ฝ ์ •์ ์˜ ๊ฐฏ์ˆ˜ $V$๊ฐ€ ๋ฌด์‹œํ•  ๋งŒํผ ์ ๋‹ค๋ฉด $O(E \cdot f_{\max})$๋ผ๊ณ  ์ ๊ธฐ๋„ ํ•œ๋‹ค.


Edmonds-Karp Algorithm

์•ž์„  <Ford-Fulkerson Algorithm>์˜ ์ฝ”๋“œ์—์„œ๋Š” DFS๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ–ˆ๋‹ค. ์ด๋•Œ, ๊ฐ„์„ ์„ ์ฐพ๋Š” ๊ณผ์ •์„ BFS๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค๋ฉด, <Edmonds-Karp Algorithm>์ด ๋œ๋‹ค!

<Edmonds-Karp Algorithm>์€ ๊ธฐ์กด <Ford-Fulkerson Algorithm>์ด ์ตœ๋Œ€ ์šฉ๋Ÿ‰ $f_{\max}$๊ฐ€ ํฐ ๊ฒฝ์šฐ์— ์ž˜ ๋™์ž‘ํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ์  ๋•Œ๋ฌธ์— ์ œ์‹œ๋œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ๊ทธ๋Ÿฐ๋ฐ DFS์—์„œ BFS๋กœ ๋ฐ”๊พธ๋ฉด ๋ฌด์—‡์ด ๋‹ฌ๋ผ์ง€๋Š” ๊ฑธ๊นŒ?

๋‹ค์‹œ ์œ„์˜ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด์ž.

์ผ๋‹จ ๋งจ์ฒ˜์Œ์—๋Š” A - B - C - D์˜ ๊ฒฝ๋กœ๋กœ ์œ ๋Ÿ‰์ด ํ˜๋ €๋‹ค๊ณ  ํ•˜์ž. ๊ทธ ๋‹ค์Œ์— ํ๋ฅผ ์œ ๋Ÿ‰์„ ์‚ดํŽด๋ณด๋ฉด,

  1. ๋ฐฉ๋ฌธ: [A], ํ: [B, C]
  2. ๋ฐฉ๋ฌธ: [A, B], ํ: [D] (B -> C๋Š” ์ด๋ฏธ ์šฉ๋Ÿ‰์ด ๋‹ค ์ฐผ๊ธฐ ๋•Œ๋ฌธ์— ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋‹ค)
  3. ๋ฐฉ๋ฌธ: [A, B, D], ํ: []
  4. 999๋งŒํผ์˜ ์œ ๋Ÿ‰์„ ํ˜๋ ค๋ณด๋‚ธ๋‹ค.

์ด ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๋ฉด ๊ธฐ์กด์˜ <Ford-Fulkerson Algorithm> ๋ณด๋‹ค ํ›จ์”ฌ ์ ์€ iteration์œผ๋กœ ์ด์œ ๋Ÿ‰์„ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

<Edmonds-Karp Algorithm>์€ flow์˜ ๊ฐ’๋ณด๋‹ค๋Š” edge $E$์— ๋” ์˜ํ–ฅ์„ ๋ฐ›๊ฒŒ ๋œ๋‹ค. ์ž์„ธํ•œ ์ฆ๋ช…์€ ๊ตฌ์‚ฌ๊ณผ๋‹˜์˜ ๋ธ”๋กœ๊ทธ๋ฅผ ํ†ตํ•ด ์‚ดํŽด๋ณด์ž ๐Ÿ˜‰ ๋‚˜์ค‘์— ์ •๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹คโ€ฆ

๊ฒฐ๋ก ์€ <Edmonds-Karp Algorithm>์ด $O(VE^2)$์˜ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ๊ฐ€์ง„๋‹ค!!


์ด๊ฒƒ์œผ๋กœ ๋„คํŠธ์›Œํฌ ํ”Œ๋กœ์šฐ ๋ฌธ์ œ์˜ ๊ธฐ๋ณธ์ ์ธ ๋‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ <Ford-Fulkerson Algorithm>๊ณผ <Edmonds-Karp Algorithm>์„ ์‚ดํŽด๋ณด์•˜๋‹ค. ๋‘ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ ๋‹ค๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ์ƒํ™ฉ์— ๋งž๊ฒŒ ์ ์ ˆํ•˜๊ฒŒ ์„ ํƒํ•ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

๋‹ค์Œ ํฌ์ŠคํŠธ๋กœ๋Š” ๋„คํŠธ์›Œํฌ ํ”Œ๋กœ์šฐ๋ฅผ ์ด์šฉํ•ด ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋“ค์— ๋Œ€ํ•ด ๋‹ค๋ฃฌ๋‹ค. ๋Œ€ํ‘œ์ ์ธ ๋ฌธ์ œ๋กœ <Bipartite Matching; ์ด๋ถ„ ๋งค์นญ>๊ณผ ๋„คํŠธ์›Œํฌ ํ”Œ๋กœ์šฐ์— ์ œ์•ฝ(constraint)๋ฅผ ์ถ”๊ฐ€ํ•œ ๋ฒ„์ „์˜ ๋ฌธ์ œ๋“ค์„ ์‚ดํŽด๋ณผ ์˜ˆ์ •์ด๋‹ค ๐Ÿ™Œ

๐Ÿ‘‰ Bipartite Matching


references

Categories:

Updated: