Pagini recente » Cod sursa (job #506429) | Cod sursa (job #1878474) | Cod sursa (job #1933890) | Cod sursa (job #2185952) | Cod sursa (job #2236995)
#include <bits/stdc++.h>
using namespace std;
template <class T>
class MaxFlow {
public:
MaxFlow(int _N, int _src, int _dest): src(_src), dest(_dest) { setN(_N); }
void setN(int _N) { N = _N, graph.resize(N); }
void setSrc(int _src) { src = _src; }
void setDest(int _dest) {dest = _dest; }
int getN() { return N; }
int getSrc() { return src; }
int getDest() { return dest; }
void addEdge(int from, int to, T forwardCap, T backwardCap = 0) {
assert(0 <= from && from < N && 0 <= to && to < N);
edges.emplace_back(from, to, 0, forwardCap);
edges.emplace_back(to, from, 0, backwardCap);
graph[from].push_back(edges.size() - 2);
graph[to].push_back(edges.size() - 1);
}
void clear() { edges.clear(), graph.clear(); }
void reset() { for (auto &edg: edges) edg.flow = 0; }
T maxflow() {
return dinic();
}
vector <int> minCut() {
vector <int> cut;
for (int i = 0; i < N; ++i)
if (dist[i] > 0)
cut.push_back(i);
return cut;
}
private:
struct Edge {
int from, to;
T flow, cap;
Edge(int _from = 0, int _to = 0, T _flow = 0, T _cap = 0):
from(_from), to(_to), flow(_flow), cap(_cap) {}
int other(int node) { return from ^ to ^ node; }
};
int N, src, dest;
vector <Edge> edges;
vector <vector <int> > graph;
vector <int> dist;
bool bfs() {
dist.clear();
dist.resize(N, 0);
queue <int> q;
dist[src] = 1;
q.push(src);
while (!q.empty()) {
const int node = q.front(); q.pop();
for (auto edg: graph[node]) {
const int son = edges[edg].other(node);
if (!dist[son] && edges[edg].cap - edges[edg].flow > 0) {
dist[son] = 1 + dist[node];
q.push(son);
}
}
}
return dist[dest] > 0;
}
T dfs(int node, T flowToPush) {
if (node == dest)
return flowToPush;
for (auto edg: graph[node]) {
const int son = edges[edg].other(node);
if (dist[son] == 1 + dist[node] && edges[edg].cap - edges[edg].flow > 0) {
T pushed = dfs(son, min(flowToPush, edges[edg].cap - edges[edg].flow));
if (pushed > 0) {
edges[edg].flow += pushed;
edges[edg ^ 1].flow -= pushed;
return pushed;
}
}
}
return 0;
}
T dinic() {
T flow = 0;
while (bfs()) {
while (1) {
T pushed = dfs(src, numeric_limits <T> :: max());
if (pushed > 0)
flow += pushed;
else
break;
}
}
return flow;
}
};
int main() {
ifstream cin("push-relabel.in");
ofstream cout("push-relabel.out");
int N;
cin >> N;
MaxFlow <int> mf(N, 0, N - 1);
for (int i = 0; i < N; ++ i) {
for (int j = 0; j < N; ++ j) {
int c;
cin >> c;
mf.addEdge(i, j, c);
}
}
cout << mf.maxflow() << endl;
return 0;
}