알고리즘 스터디
- 종만북) 31장 네트워크 유량 ~
- 백준 6086 최대 유량 O
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
//네트워크 유량 문제를 해결하는 포드-폴커슨 알고리즘의 구현
const int MAX_V = 500;
const int INF = 987654321;
int V;
//capacity[u][v] = u에서 v로 보낼 수 있는 용량
//flow[u][v] = u에서 v로 흘러가는 유량 (반대 방향인 경우 음수)
int capacity[MAX_V][MAX_V], flow[MAX_V][MAX_V];
//flow[]를 계산하고 총 유량을 반환한다.
int networkFlow(int source, int sink) {
//flow를 0으로 초기화한다.
memset(flow, 0, sizeof(flow));
int totalFlow = 0;
while (true) {
//BFS로 증가 경로를 찾는다
vector<int> parent(MAX_V, -1);
queue<int> q;
parent[source] = source;
q.push(source);
while (!q.empty() && parent[sink] == -1) {
int here = q.front();
q.pop();
for (int there = 0; there < V; ++there) {
//잔여 용량이 남아있는 간선 탐색
if (capacity[here][there] - flow[here][there] > 0 && parent[there] == -1) {
q.push(there);
parent[there] = here;
}
}
}
//증가 경로가 없는 경우 종료
if (parent[sink] == -1) break;
//증가 경로를 통해 유량을 얼마나 보낼지 결정한다
int amount = INF;
for (int p = sink; p != source; p = parent[p]) {
int r = capacity[parent[p]][p] - flow[parent[p]][p];
amount = min(r, amount);
}
//증가 경로를 통해 유량을 보낸다
for (int p = sink; p != source; p = parent[p]) {
flow[parent[p]][p] += amount;
flow[p][parent[p]] -= amount;
}
totalFlow += amount;
}
return totalFlow;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
return 0;
}