Pagini recente » Cod sursa (job #260418) | Cod sursa (job #3004738) | Cod sursa (job #607753) | Cod sursa (job #3132520) | Cod sursa (job #2679615)
#include <fstream>
#include <list>
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
#define DEFAULT_INPUT "maxflow.in"
#define DEFAULT_OUTPUT "maxflow.out"
#define MAX_N 110010
struct edge {
int y;
int c;
int rev; /* index of reversed edge in adjacency list of y */
};
class Graph {
private:
std::vector<edge> adj[MAX_N];
std::vector<edge*> level_adj[MAX_N];
int n, s, t;
int dist[MAX_N];
int pt[MAX_N];
void init() {
s = 0;
t = n - 1;
int is_source, is_sink;
// suppose there are only one source and one sink
for (int i = 0; i < n; i++) {
is_source = 1;
is_sink = 1;
for (auto e: adj[i]) {
if (e.c == 0) {
is_source = 0;
continue;
}
is_sink = 0;
}
if (is_source) {
s = i;
}
else if (is_sink) {
t = i;
}
}
}
int bfs(int node) {
std::queue<int> q;
char visited[MAX_N] = {0};
memset(dist, 0, n * sizeof(*dist));
q.push(node);
visited[node] = 1;
while (!q.empty()) {
node = q.front();
q.pop();
if (node == t) {
return 1;
}
// create leveled graph
for (auto it = adj[node].begin(); it != adj[node].end(); it++) {
int next_d = dist[node] + 1;
if (!visited[it->y] && it->c > 0) {
visited[it->y] = 1;
dist[it->y] = next_d;
q.push(it->y);
}
if (dist[it->y] == next_d) {
level_adj[node].push_back(&(*it));
}
}
}
return 0;
}
int dfs(int node, int flow) {
if (node == t) {
return flow;
}
int total = 0;
int expected = dist[node] + 1;
for (auto it = level_adj[node].begin(); it != level_adj[node].end(); it++) {
int next = (*it)->y;
if (dist[next] == expected && (*it)->c > 0) {
int child_flow = dfs(next, std::min((*it)->c, flow));
total += child_flow;
(*it)->c -= child_flow;
adj[next][(*it)->rev].c += child_flow;
flow -= child_flow;
if (flow == 0) {
return total;
}
}
}
return total;
}
public:
Graph(int n) {
this->n = n;
}
void add_edge(int x, int y, int c) {
adj[x].push_back({y, c, (int)adj[y].size()});
adj[y].push_back({x, 0, (int)(adj[x].size() - 1)});
}
int compute_max_flow() {
int max_flow = 0, flow;
init();
while (bfs(s)) {
max_flow += dfs(s, 0x7fffffff);
for (int i = 0; i < n; i++) {
level_adj[i].clear();
}
}
return max_flow;
}
};
int main(int argc, char *argv[]) {
std::ifstream fin;
std::ofstream fout;
if (argc == 1) {
fin.open(DEFAULT_INPUT);
} else {
fin.open(argv[1]);
}
int n, m, x, y, c;
fin >> n >> m;
Graph g(n);
for (int i = 0; i < m; i++) {
fin >> x >> y >> c;
x--; y--;
g.add_edge(x, y, c);
}
fin.close();
int max_flow = g.compute_max_flow();
if (argc < 3) {
fout.open(DEFAULT_OUTPUT);
std::cout << "Noo\n";
} else {
fout.open(argv[2]);
}
fout << max_flow << '\n';
fout.close();
}