Pagini recente » Cod sursa (job #3000343) | Cod sursa (job #808705) | Cod sursa (job #813171) | Cod sursa (job #2363246) | Cod sursa (job #2960424)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
ifstream f("maxflow.in");
ofstream g("maxflow.out");
int n,m, sursa;
vector<vector <int>> adiacenta;
vector<bool> visited;
vector<int> parent;
queue<int> q;
vector<vector<int>> rezidual;
int bfs (int node) {
fill(visited.begin(), visited.end(), 0);
visited[node] = 1;
//punem in coada vf de start
q.push(node);
while (!q.empty()) {
int nod_curent = q.front();
q.pop();
//mergem prin vecinii varfului scos din coada
for (auto i:adiacenta[nod_curent]) {
//daca nu a mai fost vizitata si daca are capacitatea de flux si daca nu e varful destinatie il puntem in stiva
if (!visited[i] && i!=n && rezidual[nod_curent][i]>0) {
visited[i] = 1;
q.push(i);
parent[i] = nod_curent;
}
}
}
int max_flow_possible = 0;
//daca varfurile vecine destinatiei au fost vizitate in timpul bfs ului
for (auto i : adiacenta[n]) {
if (!visited[i])
continue;
int flow_min = rezidual[i][n];
int aux = i;
//aflam fluxul minim care poate fi transportat
while (aux != 1) {
flow_min = min(flow_min, rezidual[parent[aux]][aux]);
aux = parent[aux];
}
//updatam graful rezidual , mai intai muchia vecina cu nodul destinatie dupa care ,
// folosing vectorul de tati , restul nodurilor pana la sursa
rezidual[n][i] += flow_min;
rezidual[i][n] -= flow_min;
aux = i;
while (aux != 1) {
rezidual[aux][parent[aux]] += flow_min;
rezidual[parent[aux]][aux] -= flow_min;
aux = parent[aux];
}
//adaugam in rezultat fluxul minim
max_flow_possible += flow_min;
}
return max_flow_possible;
}
int get_max_flow(){
int total_max_flow = 0;
//luam primul augmenting path
int augment_path = bfs(sursa);
//cat timp avem augmenting path
while (augment_path) {
//adaugam la rezultat ce a returnat functia
total_max_flow += augment_path;
//apelam iar functia pentru aflarea unui augmenting path
augment_path = bfs(sursa);
}
return total_max_flow;
}
int main ()
{
f>>n>> m;
adiacenta.resize(n+1);
visited.resize(n+1,0);
rezidual.resize(n+1, vector<int>(n+1, 0));
parent.resize(n+1, -1);
sursa = 1;
for (int i=0; i<m; i++) {
//citim datele si punem in lista de adiacenta si in graful rezidual
int x,y,z;
f>> x >> y >> z;
adiacenta[x].push_back(y);
adiacenta[y].push_back(x);
rezidual[x][y] += z;
}
g<<get_max_flow();
return 0;
}