Cod sursa(job #2434232)

Utilizator AlexPop28Pop Alex-Nicolae AlexPop28 Data 1 iulie 2019 12:15:34
Problema Algola Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.44 kb
#include <bits/stdc++.h>
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'

using namespace std;

struct Graph {
  int n, m, source, sink, flow;
  vector<int> parent;
  vector<unordered_map<int, int>> capacity;
  Graph(int _n) : n(_n), m(0), source(0), sink(1), flow(0) {}
  void AddEdge(int u, int v, int cap) {
    capacity[u][v] += cap;
  }
  int GetVertex(int node, int time) {
    if (m < n * time + node) {
      m = n * time + node;
      capacity.resize(m + 1);
      parent.resize(m + 1);
    }
    return n * time + node;
  }
  bool CanIncreaseFlow() {
    vector<int> q = {source};
    fill(parent.begin(), parent.end(), -1);
    parent[source] = -2;
    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[x] == -1) {
          parent[x] = node;
          q.emplace_back(x);
        }
      }
    }
    return parent[sink] != -1;
  }
  void IncreaseFlow() {
    int node = sink, added_flow = 1e9;
    while (node != source) {
      added_flow = min(added_flow, capacity[parent[node]][node]);
      node = parent[node];
    }
    node = sink;
    while (node != source) {
      capacity[parent[node]][node] -= added_flow;
      capacity[node][parent[node]] += added_flow;
      node = parent[node];
    }
    flow += added_flow;
  }
};

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, 0), 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 = 0 ; ; ++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);
      g.AddEdge(g.GetVertex(v, time), g.GetVertex(u, 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);
}