Cod sursa(job #2925811)

Utilizator retrogradLucian Bicsi retrograd Data 16 octombrie 2022 10:45:17
Problema Algola Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.33 kb
#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) 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;
}