Pagini recente » Cod sursa (job #3278976) | Diferente pentru implica-te/arhiva-educationala intre reviziile 171 si 223 | Cod sursa (job #938544) | Cod sursa (job #484048) | Cod sursa (job #3270932)
#include <bits/stdc++.h>
using namespace std;
class MaxFlow {
private:
// Structură pentru o muchie în graful rezidual
struct Edge {
int to; // nodul destinație
int rev; // indexul muchiei inverse în lista nodului 'to'
int cap; // capacitatea reziduală
};
// N = număr de noduri, adj = liste de adiacență
int N;
vector<vector<Edge>> adj;
public:
// Constructor - primește numărul de noduri (N) și redimensionează lista de adiacență
MaxFlow(int N) : N(N) {
adj.resize(N + 1); // indexare de la 1 la N
}
// Adăugăm muchia (u -> v) cu capacitatea c și muchia inversă (v -> u) cu capacitatea 0
void addEdge(int u, int v, int c) {
Edge a{v, (int)adj[v].size(), c};
Edge b{u, (int)adj[u].size(), 0};
adj[u].push_back(a);
adj[v].push_back(b);
}
// Implementarea Edmonds-Karp pentru a calcula fluxul maxim de la s la t
long long computeFlow(int s, int t) {
long long maxFlow = 0;
// Cât timp există drum de ameliorare (BFS)
while(true){
vector<int> parent(N + 1, -1);
vector<int> edgeIndex(N + 1, -1);
parent[s] = s; // marchează sursa ca vizitată
queue<int> q;
q.push(s);
// BFS pentru a găsi un drum cu capacitate > 0
while(!q.empty() && parent[t] == -1){
int u = q.front();
q.pop();
for(int i = 0; i < (int)adj[u].size(); i++){
const Edge &e = adj[u][i];
if(parent[e.to] == -1 && e.cap > 0) {
parent[e.to] = u;
edgeIndex[e.to] = i;
q.push(e.to);
if(e.to == t) break; // dacă am ajuns la destinație, ne oprim
}
}
}
// Dacă nu am ajuns la t, nu mai există drum de ameliorare
if(parent[t] == -1)
break;
// Determinăm bottleneck-ul (fluxul minim care mai poate fi împins pe acest drum)
int bottleneck = INT_MAX;
for(int v = t; v != s; ){
int u = parent[v];
int i = edgeIndex[v];
bottleneck = min(bottleneck, adj[u][i].cap);
v = u;
}
// Actualizăm valorile reziduale (scădem pe muchia directă, creștem pe cea inversă)
for(int v = t; v != s; ){
int u = parent[v];
int i = edgeIndex[v];
// Scădem capacitatea pe muchia (u -> v)
adj[u][i].cap -= bottleneck;
// Creștem capacitatea pe muchia inversă (v -> u)
int revIndex = adj[u][i].rev;
adj[v][revIndex].cap += bottleneck;
v = u;
}
maxFlow += bottleneck;
}
return maxFlow;
}
};
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
freopen ("maxflow.in", "r", stdin);
freopen ("maxflow.out", "w", stdout);
// Citim datele de intrare
int N, M;
cin >> N >> M;
// Cream obiectul MaxFlow pentru N noduri
MaxFlow mf(N);
// Citim muchiile și le adăugăm în structura noastră
for(int i = 0; i < M; i++){
int x, y, z;
cin >> x >> y >> z;
mf.addEdge(x, y, z);
}
// Calculăm fluxul maxim de la nodul 1 (sursa) la nodul N (destinația)
long long ans = mf.computeFlow(1, N);
// Afișăm rezultatul
cout << ans << "\n";
return 0;
}