Pagini recente » Cod sursa (job #2986973) | Cod sursa (job #2838392) | Cod sursa (job #778711) | Cod sursa (job #1320922) | Cod sursa (job #2970173)
#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> adjList;
int N, M;
vector<vector<int>> C;
vector<vector<int>> F;
vector<int> parent;
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
void citireGrafTastatura()
{
// Se citeste numarul de noduri si nr de muchii, dupa care se citesc muchiile
cin >> N >> M;
int x, y, c;
adjList = vector<vector<int>>(N + 1, vector<int>());
// Se citesc muchiile, fiecare avand un cost asociat
for (int i = 1; i <= M; i++)
{
cin >> x >> y >> c;
adjList[x].push_back(y);
// Se introduce si muchia inversa de capacitate 0
adjList[y].push_back(x);
}
}
void citireGrafFisier()
{
// Se citeste numarul de noduri si nr de muchii, dupa care se citesc muchiile
fin >> N >> M;
C = vector<vector<int>>(N + 1, vector<int>(N + 1, 0));
F = vector<vector<int>>(N + 1, vector<int>(N + 1, 0));
int x, y, c;
adjList = vector<vector<int>>(N + 1, vector<int>());
// Se citesc muchiile, fiecare avand un cost asociat
for (int i = 1; i <= M; i++)
{
fin >> x >> y >> c;
adjList[x].push_back(y);
adjList[y].push_back(x);
C[x][y] = c;
}
}
void fordFulkerson(int sursa, int destinatie)
{
int fluxmax = 0;
// Facem BFS-uri pana cand nu mai gasim niciun drum de crestere / lant nesaturat
bool augumentationPathFound;
queue<int> q;
vector<bool> visited = vector<bool>(N + 1, false);
parent = vector<int>(N + 1, -1);
do
{
augumentationPathFound = false;
int bottleneck = -1;
q = queue<int>();
visited = vector<bool>(N + 1, false);
bool destinationReached = false;
// Se adauga in coada nodul sursa
q.push(sursa);
while (!q.empty() && !destinationReached)
{
auto nodCurent = q.front();
visited[nodCurent] = true;
q.pop();
if (nodCurent == destinatie)
{
destinationReached = true;
break;
}
// Trecem prin vecinii nevizitati care inca mai pot primi flux
for (int i = 0; i < adjList[nodCurent].size(); i++)
{
int vecin = adjList[nodCurent][i];
if (!visited[vecin] && C[nodCurent][vecin] - F[nodCurent][vecin] > 0)
{
// Actualizam capacitatea minima nenula de pe lant
visited[vecin] = true;
q.push(vecin);
parent[vecin] = nodCurent;
}
}
}
if (destinationReached)
{
augumentationPathFound = true;
}
else
{
continue;
}
// Trecem prin fiecare muchie care apartine lantului si actualizam fluxul (respectiv capacitatea reziduala)
int curent = destinatie;
while (parent[curent] != -1)
{
if (bottleneck == -1 || C[parent[curent]][curent] - F[parent[curent]][curent] < bottleneck)
{
bottleneck = C[parent[curent]][curent] - F[parent[curent]][curent];
}
curent = parent[curent];
}
// cout << "S-a gasit un drum de crestere de la sursa la destinatie cu capacitate egala cu " << bottleneck << " si cu urmatoarele path-uri:\n";
curent = destinatie;
while (parent[curent] != -1)
{
// printf("(%d %d) ", parent[curent], curent);
// Adaugam flux pe muchia directa si scadem flux de pe muchia inversa
F[parent[curent]][curent] += bottleneck;
F[curent][parent[curent]] -= bottleneck;
curent = parent[curent];
}
fluxmax += bottleneck;
// cout << "\n";
} while (augumentationPathFound);
// cout << "Fluxul maxim este egal cu " << fluxmax << "\n";
fout << fluxmax;
}
int main()
{
citireGrafFisier();
fordFulkerson(1, N);
return 0;
}