Pagini recente » Cod sursa (job #552912) | panamasum | Metoda Greedy si problema fractionara a rucsacului | Istoria paginii runda/c1234 | Cod sursa (job #943645)
Cod sursa(job #943645)
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <limits>
using namespace std;
class Graph {
public:
explicit Graph(const int &size):
size_(size),
edges_(size),
capacity_(size, vector<int>(size, 0)),
flow_(size, vector<int>(size, 0)) {
}
void addEdge(const int &from, const int &to, int flow) {
edges_[from].push_back(to);
edges_[to].push_back(from);
capacity_[from][to] = flow;
}
int maxFlow(const int &source, const int &sink) {
int max_flow = 0;
do {
vector<int> level(size_, -1);
level[source] = 0;
vector< vector<int> > level_graph = levelGraph(source, sink);
int flow = 0;
do {
vector<int> path(size_, -1);
path[source] = source;
dfsLevelGraph(source, level_graph, path);
if (path[sink] == -1)
break;
int to_add = numeric_limits<int>::max();
for (int node = sink; node != source; node = path[node])
to_add = min(to_add, capacity_[path[node]][node] - flow_[path[node]][node]);
flow += to_add;
for (int node = sink; node != source; node = path[node]) {
flow_[path[node]][node] += to_add;
flow_[node][path[node]] -= to_add;
}
} while (true);
if (flow == 0)
break;
max_flow += flow;
} while (true);
return max_flow;
}
private:
vector< vector<int> > levelGraph(const int &source, const int &sink) {
queue<int> Q;
vector<int> level(size_, -1);
Q.push(source);
level[source] = 0;
vector< vector<int> > result(size_);
while (!Q.empty()) {
int node = Q.front();
Q.pop();
if (node == sink)
continue;
for (vector<int>::iterator it = edges_[node].begin(); it != edges_[node].end(); ++it)
if (level[*it] == -1 && flow_[node][*it] < capacity_[node][*it]) {
level[*it] = level[node] + 1;
Q.push(*it);
result[node].push_back(*it);
} else if (level[*it] == level[node] + 1) {
result[node].push_back(*it);
}
}
return result;
}
void dfsLevelGraph(const int &node, const vector< vector<int> > &edges, vector<int> &path) {
for (vector<int>::const_iterator it = edges[node].begin(); it != edges[node].end(); ++it)
if (flow_[node][*it] < capacity_[node][*it] && path[*it] == -1) {
path[*it] = node;
dfsLevelGraph(*it, edges, path);
}
}
int size_;
vector< vector<int> > edges_;
vector< vector<int> > capacity_;
vector< vector<int> > flow_;
};
int main() {
ifstream cin("maxflow.in");
ofstream cout("maxflow.out");
int N, M; cin >> N >> M;
Graph G(N);
for (int i = 0; i < M; ++i) {
int x, y, z; cin >> x >> y >> z;
G.addEdge(x - 1, y - 1, z);
}
cout << G.maxFlow(0, N - 1) << "\n";
}