Cod sursa(job #2627449)

Utilizator AokijiAlex M Aokiji Data 10 iunie 2020 20:49:38
Problema Algola Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.01 kb
#include <bits/stdc++.h>
#define DEBUG(x) cerr << (#x) << ": " << (x) << '\n'

using namespace std;

ifstream cin("algola.in");
ofstream cout("algola.out");

struct Graph
{
    int n, m, source, sink, flow;
    vector<int> parent;
    vector<unordered_map<int, int>> capacity;
    raph(int _n) : n(_n), m(1), source(0), sink(1), flow(0) {}
    void AddEdge(int u, int v, int cap)
    {
        capacity[u][v] += cap;
    }
    void resize()
    {
        m += n;
        parent.resize(m + 1);
        capacity.resize(m + 1);
    }
    int GetVertex(int node, int time)
    {
        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()
{
    int n, m; cin >> n >> m;
    Graph g(n);
    g.resize();
    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)
    {
        g.resize();
        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);
}