Pagini recente » Cod sursa (job #385332) | Cod sursa (job #2931727) | Cod sursa (job #700599) | Cod sursa (job #2522155) | Cod sursa (job #2966811)
//Ford Fulkerson Algorithm Edmonds Karp Algorithm For Max Flow
//O(VE^2)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream f("maxflow.in");
ofstream g("maxflow.out");
int N,M,source;
vector<vector <int>> graph;
vector<bool> visited;
vector<int> parent;
queue<int> q;
vector<vector<int>> residual;
//functia de bfs care va returna fluxul maxim pentru fiecare augumented path(drum de la sursa la final)
//daca fluxul maxim va fi 0 inseamna ca nu mai avem niciun augumented path posibil
int bfs (int node) {
fill(visited.begin(), visited.end(), 0);
//vizitam nodul sursa
visited[node] = 1;
//punem in coada nodul sursa
q.push(node);
while (!q.empty()) {
//scoatem pe rand din coada nodurile
int nod_curent = q.front();
q.pop();
//mergem prin vecinii nodului abia scos din coada si verifcam:
// 1. daca deja a fost vizitat atunci nu il mai vizitam
// 2. daca capacitatea reziduala este 0 atunci nu il vizitam
// 3. daca este nodul final atunci inseamna ca am obtinut un augumented path
// --->> cand ajungem la nodul final nu vom mai pune nimic in coada!
for (auto i:graph[nod_curent]) {
if (i!=N && !visited[i] && residual[nod_curent][i]>0) {
visited[i] = 1;
q.push(i);
parent[i] = nod_curent;
}
}
}
int max_flow = 0;
//daca oricare dintre nodurile vecine cu nodul final au ajuns sa fie vizitate
//atunci putem spune ca avem un augumented path si putem continua algoritmul
for (auto i : graph[N]) {
if (!visited[i])
continue;
int min_flow = residual[i][N];
int aux = i;
//ne intoarcem pe drumul gasit si calculam minimul dintre capacitatile reziduale
while (aux != 1) {
min_flow = min(min_flow, residual[parent[aux]][aux]);
aux = parent[aux];
}
residual[N][i] += min_flow;
residual[i][N] -= min_flow;
aux = i;
//ne intoarcem din nou pe drumul gasit pt a schimba capacitatile reziduale
while (aux != 1) {
residual[aux][parent[aux]] += min_flow;
residual[parent[aux]][aux] -= min_flow;
aux = parent[aux];
}
//adaugam la rezultat fluxul minim calculat mai sus
max_flow += min_flow;
}
return max_flow;
}
int get_max_flow(){
int ans = 0;
int augumented_path = bfs(source);
//pentru fiecare augumented path gasit vom adauga max flow-ul sau la raspuns
while (augumented_path) {
ans += augumented_path;
augumented_path = bfs(source);
}
return ans;
}
int main ()
{
f>>N>> M;
graph.resize(N+1);
visited.resize(N+1,0);
residual.resize(N+1, vector<int>(N+1, 0));
parent.resize(N+1, -1);
source = 1;
for (int i=0; i<M; i++) {
int x,y,z;
f>> x >> y >> z;
graph[x].push_back(y);
graph[y].push_back(x);
residual[x][y] += z;
}
g<<get_max_flow();
return 0;
}