Pagini recente » Cod sursa (job #3292478) | Cod sursa (job #3252823) | Cod sursa (job #1404004) | Cod sursa (job #3276439) | Cod sursa (job #2925816)
#include <bits/stdc++.h>
using namespace std;
using T = int;
struct Dinic {
struct Edge { int to, rev; T flow, cap; };
vector<vector<Edge>> graph;
vector<int> at, dist, q;
Dinic(int n) : graph(n) {}
void AddEdge(int a, int b, T c) {
graph[a].push_back({b, (int)graph[b].size(), 0, c});
graph[b].push_back({a, (int)graph[a].size() - 1, 0, 0});
}
bool bfs(int src, int dest) {
dist.assign(graph.size(), -1); q.clear();
dist[src] = 0; q.push_back(src);
for (int i = 0; i < (int)q.size(); ++i) {
int node = q[i];
for (const auto& e : graph[node]) {
if (dist[e.to] == -1 && e.cap > e.flow) {
dist[e.to] = dist[node] + 1;
q.push_back(e.to);
}
}
}
return dist[dest] != -1;
}
T dfs(int node, int dest, T need) {
if (!need || node == dest) return need;
T ret = 0;
for (int& i = at[node]; i < (int)graph[node].size(); ++i) {
const auto &e = graph[node][i];
if (dist[e.to] != dist[node] + 1 || e.flow == e.cap) continue;
if (T now = dfs(e.to, dest, min(need, e.cap - e.flow))) {
graph[node][i].flow += now;
graph[e.to][e.rev].flow -= now;
ret += now; need -= now;
}
if (!need) break;
}
return ret;
}
T Compute(int src, int dest) {
T ret = 0;
while (bfs(src, dest)) {
at.assign(graph.size(), 0);
ret += dfs(src, dest, numeric_limits<T>::max());
}
return ret;
}
bool SideOfCut(int x) { return dist[x] == -1; }
void Resize(int n) { graph.resize(n); }
};
int main() {
ifstream cin("algola.in");
ofstream cout("algola.out");
int n, m; cin >> n >> m;
vector<int> v(n);
T req = 0;
for (int i = 0; i < n; ++i) {
cin >> v[i];
req += v[i];
}
vector<int> a(m), b(m), c(m);
for (int i = 0; i < m; ++i) {
cin >> a[i] >> b[i] >> c[i];
--a[i]; --b[i];
}
int sz = 2 + n;
Dinic D(sz);
for (int i = 0; i < n; ++i)
D.AddEdge(0, sz - n + i, v[i]);
for (int t = 1; ; ++t) {
D.Resize(sz + n);
for (int i = 0; i < n; ++i)
D.AddEdge(sz - n + i, sz + i, req);
for (int i = 0; i < m; ++i) {
D.AddEdge(sz - n + a[i], sz + b[i], c[i]);
D.AddEdge(sz - n + b[i], sz + a[i], c[i]);
}
D.AddEdge(sz, 1, req);
sz += n;
req -= D.Compute(0, 1);
if (req == 0) {
cout << t << endl;
return 0;
}
}
return 0;
}