Cod sursa(job #2114428)

Utilizator Mihai_PredaPreda Mihai Dragos Mihai_Preda Data 25 ianuarie 2018 16:29:24
Problema Algola Scor 60
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.53 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

const int INF = 30000;

class flow
{
public:
    flow(int n, int source, int dest)
    {
        this->source = source;
        this->dest = dest;
        this->n = n;
        cap.resize(n + 1, vector<short>(n + 1));
        flux.resize(n + 1, vector<short>(n + 1));
        vecini.resize(n + 1);
        viz.resize(n + 1);
        father.resize(n + 1);
    }
    void AddEdge(int x, int y, int c)
    {
        if(cap[x][y] == 0 && cap[y][x] == 0)
        {
            vecini[x].push_back(y);
            vecini[y].push_back(x);
        }
        cap[x][y] += c;
    }
    int GetMaxFlow()
    {
        int ret = 0;
        BFS();
        while(viz[dest])
        {
            for(auto nod:vecini[dest])
            {
                if(cap[nod][dest] == flux[nod][dest] || viz[nod] == false)
                    continue;
                father[dest] = nod;

                int mn = cap[father[dest]][dest] - flux[father[dest]][dest];
                nod = father[dest];
                while(nod != source)
                {
                    mn = min(mn, cap[father[nod]][nod] - flux[father[nod]][nod]);
                    nod = father[nod];
                }

                nod = dest;
                while(nod != source)
                {
                    flux[father[nod]][nod] += mn;
                    flux[nod][father[nod]] -= mn;
                    nod = father[nod];
                }

                ret += mn;
            }
            BFS();
        }
 //       cout << ret << "\n";
        return ret;
    }
    int source, dest;
private:
    void BFS()
    {
        fill(viz.begin(), viz.end(), false);
        queue<int> q;
        q.push(source);
        viz[source] = true;
        while(q.empty() == false)
        {
            int nod = q.front();
            q.pop();
            if(nod == dest)
                continue;
            for(auto v:vecini[nod])
            {
                if(cap[nod][v] == flux[nod][v] || viz[v])
                    continue;
                viz[v] = true;
                q.push(v);
                father[v] = nod;
            }
        }
    }
    int n;
    vector<bool> viz;
    vector<vector<short> > vecini;
    vector<vector<short> > cap;
    vector<vector<short> > flux;
    vector<int> father;
};


struct edge
{
    int x, y, cap;
};

int main()
{
    ifstream in("algola.in");
    int n, m;
    in >> n >> m;
    vector<int> cap(n+1);
    int total = 0;
    for(int i = 1; i <= n; ++i)
        in >> cap[i], total += cap[i];
    vector<edge> edges(m);
    for(int i = 0; i < m; ++i)
        in >> edges[i].x >> edges[i].y >> edges[i].cap;
    in.close();
    const int MAX_TIME = 2 * n;
    int source = n * MAX_TIME + 1, dest = 1;
    flow gr(source, source, dest);
    for(int i = 1; i <= n; ++i)
        gr.AddEdge(source, i, cap[i]);
    int time = 1;
    int flow = 0;
    while((flow += gr.GetMaxFlow()) < total)
    {
        int lastId = n * (time - 1), currentId = n * time;
        for(int i = 1; i <= n; ++i)
            gr.AddEdge(lastId + i, currentId + i, INF);
        for(auto &e:edges)
        {
            gr.AddEdge(lastId + e.x, currentId + e.y, e.cap);
            gr.AddEdge(lastId + e.y, currentId + e.x, e.cap);
        }
        gr.dest = currentId + 1;
        time++;
    }
    ofstream out("algola.out");
    out << time-1;
    out.close();
    return 0;
}