-
[BOJ] #6086 _ 최대 유량Problem Solving/BOJ 2020. 3. 9. 01:43
[최대 유량] https://www.acmicpc.net/problem/6086
6086번: 최대 유량
문제 농사꾼 존은 소들이 충분한 물을 마시길 원했다. 그래서 농장에서 우물에서 외양간을 잇는 N개의 배수관의 지도를 만들기로 했다. 존은 아주 다양한 크기의 배수관들이 완전히 우연한 방법으로 연결돼있음을 알았다. 존은 파이프를 통과하는 유량을 계산하고 싶다. 두개의 배수관이 한줄로 연결 돼 있을 때 두 관의 유량 중 최솟값으로 흐르게 된다. 예를 들어 용량이 5인 파이프가 용량이 3인 파이프와 연결되면 한개의 용량 3짜리 파이프가 된다. +---5---+
www.acmicpc.net
네트워크 플로우 문제이다.
해당 문제는 양방항 그래프라는 점을 유의해서 풀어야 한다.
[ Ford-Fulkerson Algorithm ]
#include <cstdio> #include <queue> #include <vector> #include <cstring> #include <algorithm> #define MAX 52 #define INF 999999999 using namespace std; int c[MAX][MAX], f[MAX][MAX], visit[MAX]; vector<int> adj[MAX]; int charToint(char chr); int maxFlow(int S, int T); int dfs(int a, int T, int flow); int main() { int N, capacity; char p1, p2, tmp; scanf("%d%c", &N, &tmp); for (int i = 0; i < N; i++) { int a, b; scanf("%c %c %d%c", &p1, &p2, &capacity, &tmp); a = charToint(p1); b = charToint(p2); adj[a].push_back(b); adj[b].push_back(a); c[a][b] += capacity; c[b][a] += capacity; } printf("%d\n", maxFlow(charToint('A'), charToint('Z'))); return 0; } int charToint(char chr) { if (chr < 'a') return chr - 'A'; else return (chr - 'a') + 26; } int maxFlow(int S, int T) { int result = 0; while (1) { memset(visit, 0, sizeof(visit)); int flow = dfs(S, T, INF); if (!flow) break; result += flow; } return result; } int dfs(int a, int T, int flow) { if (visit[a]) return 0; visit[a] = 1; if (a == T) return flow; for (int i = 0; i < adj[a].size(); i++) { int b = adj[a][i], now_flow = c[a][b] - f[a][b]; if (now_flow <= 0) continue; int result = dfs(b, T, min(flow, now_flow)); if (result) { f[a][b] += result; f[b][a] -= result; return result; } } return 0; }
[ Edmonds-Karp Algorithm ]
#include <cstdio> #include <queue> #include <vector> #include <cstring> #include <algorithm> #define MAX 52 #define INF 999999999 using namespace std; int c[MAX][MAX], f[MAX][MAX], visit[MAX]; vector<int> adj[MAX]; int charToint(char chr); int maxFlow(int S, int T); int bfs(int S, int T); int main() { int N, capacity; char p1, p2, tmp; scanf("%d%c", &N, &tmp); for (int i = 0; i < N; i++) { int a, b; scanf("%c %c %d%c", &p1, &p2, &capacity, &tmp); a = charToint(p1); b = charToint(p2); adj[a].push_back(b); adj[b].push_back(a); c[a][b] += capacity; c[b][a] += capacity; } printf("%d\n", maxFlow(charToint('A'), charToint('Z'))); return 0; } int charToint(char chr) { if (chr < 'a') return chr - 'A'; else return (chr - 'a') + 26; } int maxFlow(int S, int T) { int result = 0; while (1) { int flow = bfs(S, T); if (!flow) break; result += flow; } return result; } int bfs(int S, int T) { memset(visit, -1, sizeof(visit)); queue<int> q; q.push(S); while (!q.empty()) { int a = q.front(); q.pop(); for (int i = 0; i < adj[a].size(); i++) { int b = adj[a][i]; if (c[a][b] - f[a][b] <= 0) continue; if (visit[b] != -1) continue; q.push(b); visit[b] = a; if (b == T) break; } } if (visit[T] == -1) return 0; int flow = INF; for (int i = T; i != S; i = visit[i]) { flow = min(flow, c[visit[i]][i] - f[visit[i]][i]); } for (int i = T; i != S; i = visit[i]) { f[visit[i]][i] += flow; f[i][visit[i]] -= flow; } return flow; }
'Problem Solving > BOJ' 카테고리의 다른 글
[BOJ] #7616 _ 교실로 가는 길 (0) 2020.03.09 [BOJ] #17472 _ 다리 만들기 2 (0) 2019.10.22 [BOJ] #17471 _ 게리맨더링 (0) 2019.10.22 [BOJ] #17281 _ 야구 (0) 2019.10.22 [BOJ] #17144 _ 미세먼지 안녕! (0) 2019.10.22