Cod sursa(job #2735154)

Utilizator Tudor_PascaTudor Pasca Tudor_Pasca Data 1 aprilie 2021 21:23:54
Problema Algola Scor 0
Compilator cpp-32 Status done
Runda Arhiva de probleme Marime 2.87 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>

using namespace std;

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

const int INF = 0x3f3f3f3f3f3f3f3f;

int n, m, current, T, total, source;
int start[55], sourceCap[55], cap[10000][10000], flow[10000][10000], father[10000];
bool fr[10000];
vector<vector<int>> adj, original;

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

    cap[x][y] = c;
    cap[y][x] = c;
}

void bfs()
{
    memset(fr, 0, sizeof fr);
    fr[source] = 1;

    queue<int> q;
    q.push(source);

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

        if(node == 0)
            continue;

        //cout << "NODE: " << node << '\n';

        for(auto it: adj[node])
        {
            //cout << it << ' ' << fr[it] << ' ' << cap[node][it] - flow[node][it] << ' ' << cap[node][it] << ' ';
            if(!fr[it] && (cap[node][it] - flow[node][it] > 0))
            {
                //cout << "All good!";
                father[it] = node;
                fr[it] = 1;
                q.push(it);
            }
            //cout << '\n';
        }
    }
}

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

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

    source = n + 1;

    for(int i = 1; i <= n; i++)
    {
        in >> sourceCap[i];

        total += sourceCap[i];

        addEdge(source, i, sourceCap[i]);
    }

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

        original[x].push_back(y);
        original[y].push_back(x);

        addEdge(x, y, c);
    }

    addEdge(1, 0, total);

    do{
        //cout << "NEW: " << T << '\n';
        bfs();

        father[0] = 1 + (n * T);

        int bottleNeck = INF;

        for(int i = 0; i != source; i = father[i])
        {
            //cout << i << '\n';
            bottleNeck = min(bottleNeck, cap[father[i]][i] - flow[father[i]][i]);
        }

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

        adj.resize(n * (T + 3));
        adj[source].clear();

        for(int i = 1; i <= n; i++)
        {
            cap[source][i] = 0;
            addEdge(source + n, i, sourceCap[i]);
        }

        source += n;

        addEdge(1 + (n * (T + 1)), 0, total);

        for(int i = 1; i <= n; i++)
        {
            addEdge(i + (n * T), i + (n * (T + 1)), INF);

            for(auto it: original[i])
                addEdge(i + (n * T), it + (n * (T + 1)), cap[i][it]);
        }

        current += cap[1 + (n * T)][0] - flow[1 + (n * T)][0];

        T++;

    }while(current < total);

    out << T << '\n';

    return 0;
}