Pagini recente » Cod sursa (job #1557171) | Cod sursa (job #933613) | Cod sursa (job #16550) | Cod sursa (job #179485) | Cod sursa (job #2434071)
#include <bits/stdc++.h>
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'
using namespace std;
struct Graph {
int n, source, sink, flow;
unordered_map<int, int> parent;
unordered_map<int, unordered_map<int, int>> capacity;
Graph(int _n) : n(_n), source(0), sink(1), flow(0) {}
void AddEdge(int u, int v, int cap) {
capacity[u][v] += cap;
capacity[v][u] += cap;
//~ cerr << "Add edge: " << u << ' ' << v << ' ' << cap << endl;
}
int GetVertex(int node, int time) {
return n * time + node;
}
bool CanIncreaseFlow() {
vector<int> q = {source};
parent.clear();
for (int i = 0; i < (int)q.size(); ++i) {
int node = q[i];
for (auto &p : capacity[node]) {
int x, cap; tie(x, cap) = p;
if (cap > 0 && parent.find(x) == parent.end()) {
parent[x] = node;
q.emplace_back(x);
}
}
}
//~ for (auto &p : parent) {
//~ cerr << "Parent of: " << p.first << " is: " << p.second << endl;
//~ }
return parent.find(sink) != parent.end();
}
void IncreaseFlow() {
for (auto it = capacity[sink].begin(); it != capacity[sink].end(); ++it) {
int x = it->first;
int added_flow = capacity[x][sink];
if (!added_flow) {
continue;
}
int node = x;
while (parent[node] != source) {
added_flow = min(added_flow, capacity[parent[node]][node]);
node = parent[node];
}
added_flow = min(added_flow, capacity[source][node]);
node = x;
while (parent[node] != source) {
capacity[parent[node]][node] -= added_flow;
capacity[node][parent[node]] += added_flow;
node = parent[node];
}
capacity[source][node] -= added_flow;
capacity[node][source] += added_flow;
flow += added_flow;
//~ cerr << "Flow increased with: " << added_flow << endl;
}
}
};
int main() {
ifstream cin("algola.in");
ofstream cout("algola.out");
int n, m; cin >> n >> m;
Graph g(n);
int total = 0;
bool ans_zero = true;
for (int i = 2; i <= n + 1; ++i) {
int cap; cin >> cap;
total += cap;
if (cap && i != 2) ans_zero = false;
g.AddEdge(g.source, g.GetVertex(i, 1), cap);
}
if (ans_zero) {
cout << "0\n";
return 0;
}
vector<tuple<int, int, int>> edges(m);
for (int i = 0; i < m; ++i) {
int u, v, cap; cin >> u >> v >> cap;
edges[i] = make_tuple(u + 1, v + 1, cap);
}
for (int time = 1 ; ; ++time) {
for (auto &e : edges) {
int u, v, cap; tie(u, v, cap) = e;
g.AddEdge(g.GetVertex(u, time), g.GetVertex(v, time + 1), cap);
}
for (int i = 2; i <= n + 1; ++i) {
g.AddEdge(g.GetVertex(i, time), g.GetVertex(i, time + 1), total);
}
g.AddEdge(g.GetVertex(2, time), g.sink, total);
while (g.CanIncreaseFlow()) {
g.IncreaseFlow();
}
if (g.flow == total) {
cout << time << endl;
return 0;
}
}
assert(false);
}