Cod sursa(job #2587002)

Utilizator IulianOleniucIulian Oleniuc IulianOleniuc Data 21 martie 2020 20:57:23
Problema Algola Scor 90
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.68 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fin("algola.in");
ofstream fout("algola.out");

struct Triple {
    int x, y, z;
};

class FlowNetwork {
  private:
    int n, s, t;
    vector<vector<int>> ad, cap;

    bool bfs(vector<bool>& vis, vector<int>& father) {
        fill(vis.begin(), vis.end(), false);
        vis[s] = true;
        queue<int> q; q.push(s);
        while (!q.empty()) {
            int node = q.front(); q.pop();
            for (int nghb : ad[node])
                if (!vis[nghb] && cap[node][nghb]) {
                    vis[nghb] = true;
                    father[nghb] = node;
                    if (nghb != t)
                        q.push(nghb);
                }
        }
        return vis[t];
    }

  public:
    FlowNetwork(int n, int s, int t) :
        n(n), s(s), t(t), ad(2500),
        cap(2500, vector<int>(2500)) { }

    void addNodes(int x) {
        n += x;
    }

    void addEdge(int x, int y, int z = 1e9) {
        ad[x].push_back(y);
        ad[y].push_back(x);
        cap[x][y] = z;
    }

    int maxFlow() {
        vector<bool> vis(n + 1);
        vector<int> father(n + 1);
        int maxFlow = 0;
        while (bfs(vis, father))
            for (int nghb : ad[t])
                if (vis[nghb] && cap[nghb][t]) {
                    int flow = 1e9;
                    father[t] = nghb;
                    for (int i = t; i != s; i = father[i])
                        flow = min(flow, cap[father[i]][i]);
                    for (int i = t; i != s; i = father[i]) {
                        cap[father[i]][i] -= flow;
                        cap[i][father[i]] += flow;
                    }
                    maxFlow += flow;
                }
        return maxFlow;
    }
};

int main() {
    int n, m; fin >> n >> m;
    auto id = [n](int node, int time) {
        return time * n + node + 1;
    };

    int total = 0;
    FlowNetwork graph(n + 1, 0, 1);
    for (int i = 1; i <= n; i++) {
        int x; fin >> x; total += x;
        graph.addEdge(0, id(i, 0), x);
    }
    graph.addEdge(id(1, 0), 1);

    vector<Triple> edges(m);
    for (int i = 0; i < m; i++)
        fin >> edges[i].x >> edges[i].y >> edges[i].z;

    int flow = 0, time = -1;
    do {
        time++;
        flow += graph.maxFlow();
        graph.addNodes(n);
        for (int i = 1; i <= n; i++)
            graph.addEdge(id(i, time), id(i, time + 1));
        graph.addEdge(id(1, time + 1), 1);
        for (auto& edge : edges) {
            graph.addEdge(id(edge.x, time), id(edge.y, time + 1), edge.z);
            graph.addEdge(id(edge.y, time), id(edge.x, time + 1), edge.z);
        }
    } while (flow < total);
    fout << time << '\n';

    fout.close();
    return 0;
}