dh-winternagi 님의 블로그
(8551) Blokada 본문
https://www.acmicpc.net/problem/8551
단계별로 풀어보기
54단계(네크워크 플로우 1) 6번째
모든 간선의 최대 유량이 0 또는 1이라면 디닉 알고리즘은 O(E)만에 해를 구할 수 있다고 한다.

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#define SIZE 10001
#define INF 1000000001
using namespace std;
struct Edge;
int s, e;
vector<Edge> adj[SIZE];
int level[SIZE], work[SIZE];
struct Edge{
int to, cap, flux, rev;
Edge(int to1, int cap1, int rev1): to(to1), cap(cap1), flux(0), rev(rev1){}
int spare(){
return cap-flux;
}
};
void addedge(int u, int v, int capacity){
int uidx= adj[u].size();
int vidx= adj[v].size();
adj[u].push_back(Edge(v, capacity, vidx));
adj[v].push_back(Edge(u, 0, uidx));
}
bool leveling(){
queue<int> q;
fill_n(level, SIZE, 0);
level[s]= 1;
q.push(s);
while(!q.empty()){
int now= q.front();
q.pop();
for(Edge &edge: adj[now]){
int next= edge.to;
if(!level[next] && edge.spare()>0){
level[next]= level[now]+1;
q.push(next);
}
}
}
return level[e];
}
int dfs(int now, int nowflow){
if(now==e) return nowflow;
for(int &i= work[now];i<adj[now].size();i++){
Edge &edge= adj[now][i];
int next= edge.to;
if(level[next]==level[now]+1 && edge.spare()>0){
int flow= dfs(next, min(nowflow, edge.spare()));
if(flow>0){
adj[now][i].flux+= flow;
adj[next][edge.rev].flux-= flow;
return flow;
}
}
}
return 0;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m, ans= 0;
cin >> n >> m;
s= 1; e= n;
while(m--){
int a, b;
cin >> a >> b;
addedge(a, b, 1);
}
int s= 1, e= n;
while(leveling()){
fill_n(work, SIZE, 0);
while(1){
int flow= dfs(s, INF);
if(flow) ans+= flow;
else break;
}
}
cout << ans;
return 0;
}'백준 (C++) > Solve' 카테고리의 다른 글
| (2365) 숫자판 만들기 (0) | 2026.04.28 |
|---|---|
| (1420) 학교 가지마! (0) | 2026.04.28 |
| (13161) 분단의 슬픔 (0) | 2026.04.28 |
| (2316) 도시 왕복하기 2 (0) | 2026.04.28 |
| (14750) Jerry and Tom (0) | 2026.04.28 |
