Pagini recente » Cod sursa (job #1349993) | Monitorul de evaluare | Cod sursa (job #2406294) | Cod sursa (job #3138255) | Cod sursa (job #1808311)
#include <fstream>
#include <vector>
#include <queue>
#include <limits.h>
#include <string.h>
#include <iostream>
#define NMAX 1001
using namespace std;
typedef vector< vector<int> > Graph;
int F[NMAX][NMAX]; // fluxul pe muchia i -> j
int C[NMAX][NMAX]; // capacitatea muchiei i -> j
bool visited[NMAX]; // nodul i vizitat in bfs sau nu
int previous[NMAX]; // precedentul lui i in bfs
/* intoarce true daca ajunge la destinatie
definitia mai jos (altfel aveam niste erori de la variabilele globale) */
bool bfs(Graph &graph, int n);
int main()
{
ifstream fin("maxflow.in");
ofstream fout("maxflow.out");
int n, m;
int fmin; // minimul pe o cale
int total_flow;
int prevn; // un precedent al lui n
fin >> n >> m;
Graph graph(n + 1);
int v1, v2, capacity;
for (int i = 1; i <= m; i++) {
fin >> v1 >> v2 >> capacity;
graph[v1].push_back(v2); // muchie directa, cu capacitatea data
graph[v2].push_back(v1); // muchie inversa, capacitate 0
C[v1][v2] += capacity; // poti avea mai multe muchii intre doua noduri
}
total_flow = 0;
do {
// daca nu mai exista drum de la 1 la n, break
if(!bfs(graph, n)) {
break;
}
// incercam sa folosim drumul gasit adineauri pentru mai multi predecesori
// ai lui n (ii putem gasi pt ca am pus in graf si muchiile inverse)
for (unsigned int i = 0; i < graph[n].size(); i++) {
prevn = graph[n][i];
// daca muchia este deja saturata sau prevn nu apartine drumului
// gasit, o ignoram
if (F[prevn][n] == C[prevn][n] || !visited[prevn]) {
continue;
}
// gasim reziduul maxim ramas pe drum
previous[n] = prevn;
fmin = INT_MAX;
for (int j = n; j != 1; j = previous[j]) {
fmin = min(fmin, C[previous[j]][j] - F[previous[j]][j]);
}
if (fmin == 0) {
continue;
}
// actualizam flow-urile
for (int j = n; j != 1; j = previous[j]) {
F[previous[j]][j] += fmin;
F[j][previous[j]] -= fmin;
}
total_flow += fmin;
}
} while (true);
fout << total_flow;
return 0;
}
bool bfs(Graph &graph, int n) {
memset(visited, false, NMAX * sizeof(bool));
queue<int> bfs_q;
bfs_q.push(1);
visited[1] = true;
int node, next;
while(!bfs_q.empty()) {
node = bfs_q.front();
bfs_q.pop();
// gasim intr-un bfs drumuri spre toti predecesorii lui n => nu ne
// oprim cand dam de n
if (node == n) {
continue;
}
for (unsigned int i = 0; i < graph[node].size(); i++) {
next = graph[node][i];
if (C[node][next] > F[node][next] && !visited[next]) {
visited[next] = true;
bfs_q.push(next);
previous[next] = node;
}
}
}
return visited[n];
}