Cod sursa(job #2663462)

Utilizator Tudor_PascaTudor Pasca Tudor_Pasca Data 26 octombrie 2020 14:41:52
Problema Algola Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.54 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, totalFlow, total, SINK = 5000, T;
int cap[5010][5010], flow[5010][5010], father[5010];
bool use[5010];
vector<vector<int>> adj;
vector<vector<pair<int, int>>> network;

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(use, false, sizeof use);
    memset(father, 0, sizeof father);

    queue<int> q;
    q.push(0);
    use[0] = true;

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

        if(node == SINK)
            continue;

        for(auto it: adj[node])
        {
            if(!use[it] && (cap[node][it] - flow[node][it]))
            {
                father[it] = node;
                q.push(it);
                use[it] = true;
            }
        }
    }

    return use[SINK];
}

void maxFlow()
{
    while(BFS())
    {
        for(auto it: adj[SINK])
        {
            if(use[it] && (cap[it][SINK] - flow[it][SINK] > 0))
            {
                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;
                }

                totalFlow += bottleNeck;
            }
        }
    };
}

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

    adj.resize(5010);
    network.resize(55);

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

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

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

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

    addEdge(1, SINK, INF);

    maxFlow();

    while(totalFlow < total)
    {
        T++;

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

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

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

        maxFlow();
    }

    out << T << '\n';

    return 0;
}