Cod sursa(job #2735238)

Utilizator Tudor_PascaTudor Pasca Tudor_Pasca Data 2 aprilie 2021 08:52:09
Problema Algola Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.86 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<cstring>
#include<queue>

using namespace std;

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

const int INF = 0x3f3f3f3f3f3f3f3f;

int n, m, total, current, SINK = 5000, T;
int cap[5010][5010], flow[5010][5010], father[5010];
bool fr[5010];
vector<vector<int>> adj;
vector<vector<pair<int, int>>> original;

void addEdge(int x, int y, int c)
{
    adj[x].push_back(y);
    adj[y].push_back(x);
    cap[x][y] = c;
}

bool BFS()
{
    memset(fr, 0, sizeof fr);
    memset(father, 0, sizeof father);
    //memset(flow, 0, sizeof flow);

    queue<int> q;

    fr[0] = 1;
    q.push(0);

    while(!q.empty())
    {
        int node = q.front();
        q.pop();

        //cout << node << '\n';

        if(node == SINK)
            continue;

        for(auto it: adj[node])
        {
            if(fr[it] == 0 && (cap[node][it] - flow[node][it] > 0))
            {
                fr[it] = 1;
                father[it] = node;

                q.push(it);
            }
        }
    }

    //cout << "FREQUENCY: " << fr[SINK] << '\n';
    return fr[SINK];
}

void maxFlow()
{
    //cout << "T I M E: " << T << '\n';

    while(BFS())
    {
        //cout << "GOT HERE!\n";

        for(auto it: adj[SINK])
        {
            //cout << it << '\n';

            if(fr[it] && (cap[it][SINK] - flow[it][SINK] > 0))
            {
                //cout << "PASSED\n";

                int bottleNeck = INF;
                father[SINK] = it;

                for(int i = SINK; i != 0; i = father[i])
                    bottleNeck = min(bottleNeck, cap[father[i]][i] - flow[father[i]][i]);

                for(int i = SINK; i != 0; i = father[i])
                {
                    flow[father[i]][i] += bottleNeck;
                    flow[i][father[i]] -= bottleNeck;
                }

                current += bottleNeck;
                //cout << current << "\n\n";
            }
        }
    }
}

int main()
{
    in >> n >> m;

    adj.resize(SINK + 5);
    original.resize(n + 5);

    for(int i = 1; i <= n; i++)
    {
        int x;
        in >> x;

        total += x;
        addEdge(0, i, x);
    }

    for(int i = 1; i <= m; i++)
    {
        int x, y, c;
        in >> x >> y >> c;

        original[x].emplace_back(y, c);
        original[y].emplace_back(x, c);
    }

    addEdge(1, SINK, INF);

    maxFlow();

    while(current < total)
    {
        T++;

        addEdge(1 + n * T, SINK, INF);

        for(int i = 1; i <= n; i++)
        {
            for(auto it: original[i])
                addEdge(i + n * (T - 1), it.first + n * T, it.second);

            addEdge(i + n * (T - 1), i + n * T, INF);
        }

        maxFlow();
    }

    out << T << '\n';

    return 0;
}