Hướng dẫn cho Luồng Cực Đại Trên Mạng
Chỉ sử dụng khi thực sự cần thiết như một cách tôn trọng tác giả và người viết hướng dẫn này.
Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.
Chép code từ bài hướng dẫn để nộp bài là hành vi có thể dẫn đến khóa tài khoản.
Authors:
Các code dưới đây có thể không AC được bài này nên các bạn chỉ tham khảo, tuyệt đối không được chép code, nếu phát hiện sẽ có thể bị ban.
Code Pascal
Delphi
{$MODE DELPHI}
program maxflow;
const
input = '';
output = '';
maxn = 1000;
type
PNode = ^TNode;
TNode = record
adj: integer;
link: PNode;
end;
var
c,f: array[1..maxn,1..maxn] of integer;
trace,queue: array[1..maxn] of integer;
n,m,s,t: integer;
a: array[1..maxn] of PNode;
procedure add(u,v: integer);
var
P: PNode;
begin
New(P);
P^.adj := v;
P^.link := a[u];
a[u] := P;
end;
procedure init;
var
fi: text;
i,u,v: integer;
begin
assign(fi, input);
reset(fi);
readln(fi, n, m, s, t);
fillchar(c, sizeof(c), 0);
fillchar(f, sizeof(f), 0);
for i := 1 to m do
begin
readln(fi, u, v, c[u,v]);
add(u,v);
end;
close(fi);
end;
function FindPath: boolean;
var
va,st,front,rear: integer;
u: PNode;
begin
fillchar(trace, sizeof(trace), 0);
front := 1;
rear := 1;
queue[1] := s;
trace[s] := -1;
repeat
st := queue[front];
inc(front);
u := a[st];
while u <> nil do
begin
va := u^.adj;
if (trace[va] = 0) and (c[st,va] > f[st,va]) then
begin
trace[va] := st;
if va = t then exit(true);
inc(rear);
queue[rear] := va;
end;
u := u^.link;
end;
until front > rear;
FindPath := false;
end;
procedure IncFlow;
var
delta,u,v: integer;
begin
delta := high(longint);
v := t;
repeat
u := trace[v];
if c[u,v] - f[u,v] < delta then delta := c[u,v] - f[u,v];
v := u;
until v = s;
v := t;
repeat
u := trace[v];
f[u,v] := f[u,v] + delta;
f[v,u] := f[v,u] - delta;
v := u;
until v = s;
end;
procedure FordFulkerson;
begin
repeat
if not FindPath then break;
IncFlow;
until false;
end;
procedure printresult;
var
fo: text;
cost,i,j: integer;
begin
assign(fo, output);
rewrite(fo);
cost := 0;
for i := 1 to n do
if f[s,i] > 0 then cost := cost + f[s,i];
writeln(fo, cost);
close(fo);
end;
begin
init;
FordFulkerson;
printresult;
end.
Code C++
C++
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int oo = 1 << 29;
struct edge
{
int x, y, cap, flow;
};
struct Flow
{
int n, S, T;
vector < vector <int> > a;
vector <int> cur, d;
vector <edge> e;
Flow() {}
Flow(int _n, int _S, int _T)
{
n = _n; S = _S; T = _T;
a = vector < vector <int> >(n + 1);
cur = vector <int>(n + 1);
d = vector <int>(n + 1);
}
void addEdge(int x, int y, int _cap)
{
edge e1 = {x, y, _cap, 0};
edge e2 = {y, x, 0, 0};
a[x].push_back(e.size()); e.push_back(e1);
a[y].push_back(e.size()); e.push_back(e2);
}
int bfs()
{
queue <int> q;
for (int i = 1; i <= n; i++) d[i] = -1;
q.push(S); d[S] = 0;
while (!q.empty() && d[T] < 0)
{
int x = q.front(); q.pop();
for (int i = 0; i < int(a[x].size()); i++)
{
int id = a[x][i], y = e[id].y;
if (d[y] < 0 && e[id].flow < e[id].cap)
q.push(y), d[y] = d[x] + 1;
}
}
return d[T] >= 0;
}
int dfs(int x, int val)
{
if (!val) return 0;
if (x == T) return val;
for (; cur[x] < int(a[x].size()); cur[x]++)
{
int id = a[x][cur[x]], y = e[id].y;
if (d[y] != d[x] + 1) continue;
int pushed = dfs(y, min(val, e[id].cap - e[id].flow));
if (pushed)
{
e[id].flow += pushed;
e[id ^ 1].flow -= pushed;
return pushed;
}
}
return 0;
}
int maxFlow()
{
int res = 0;
while (bfs())
{
for (int i = 1; i <= n; i++) cur[i] = 0;
while (1)
{
int val = dfs(S, oo);
if (!val) break;
res += val;
}
}
return res;
}
};
int main()
{
int n, m, S, T, x, y, z;
cin >> n >> m >> S >> T;
Flow u(n, S, T);
while (m--)
{
scanf("%d%d%d", &x, &y, &z);
u.addEdge(x, y, z);
}
cout << u.maxFlow() << endl;
}
Code Python
Python
import sys
from collections import deque
sys.setrecursionlimit(200000)
INF = 10**9
class Edge:
def __init__(self, u, v, capacity, flow=0):
self.u = u
self.v = v
self.capacity = capacity
self.flow = flow
class Network:
def __init__(self, n, s, t):
self.n = n
self.source = s
self.sink = t
self.a = [[] for _ in range(n + 1)]
self.E = []
self.cur = [0] * (n + 1)
self.dist = [-1] * (n + 1)
def addEdge(self, u, v, c):
self.a[u].append(len(self.E))
self.E.append(Edge(u, v, c, 0))
self.a[v].append(len(self.E))
self.E.append(Edge(v, u, 0, 0))
def bfs(self):
self.dist = [-1] * (self.n + 1)
self.dist[self.source] = 0
Q = deque([self.source])
while Q:
u = Q.popleft()
for idx in self.a[u]:
edge = self.E[idx]
v = edge.v
if self.dist[v] == -1 and edge.flow < edge.capacity:
self.dist[v] = self.dist[u] + 1
Q.append(v)
return self.dist[self.sink] != -1
def dfs(self, u, flow):
if flow == 0 or u == self.sink:
return flow
while self.cur[u] < len(self.a[u]):
idx = self.a[u][self.cur[u]]
edge = self.E[idx]
v = edge.v
if self.dist[v] != self.dist[u] + 1:
self.cur[u] += 1
continue
delta = self.dfs(v, min(flow, edge.capacity - edge.flow))
if delta > 0:
edge.flow += delta
self.E[idx ^ 1].flow -= delta
return delta
self.cur[u] += 1
return 0
def maxFlow(self):
ans = 0
while self.bfs():
self.cur = [0] * (self.n + 1)
while True:
delta = self.dfs(self.source, INF)
if delta == 0:
break
ans += delta
return ans
def main():
input = sys.stdin.readline
try:
line = input().split()
if not line:
return
n, m, s, t = map(int, line)
G = Network(n, s, t)
for _ in range(m):
u, v, c = map(int, input().split())
G.addEdge(u, v, c)
print(G.maxFlow())
except ValueError:
pass
if __name__ == "__main__":
main()
Bình luận