Cod sursa(job #1970633)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 19 aprilie 2017 15:01:52
Problema Flux maxim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.46 kb
#include <bits/stdc++.h>

using namespace std;

#define FILE_IO

typedef pair<int, int> pii;
typedef pair<pii, int> p3i;

class EdmondsKarp
{
public:
    int N, M, S, T;
    vector <p3i> edges;
    int cp[2005][2005];
    vector <int> edg[2005];
    int d[2005], f[2005];

    EdmondsKarp()
    {
        N = M = S = T = 0;
        memset(cp, 0, sizeof(cp));
        memset(d, 0, sizeof(d));
        memset(f, 0, sizeof(f));
    }

    void addEdge(int x, int y, int c)
    {
        edges.push_back({{x, y}, c});
    }

    void createGraph()
    {
        memset(cp, 0, sizeof(cp));
        for(auto e: edges)
        {
            N = max(N, max(e.first.first, e.first.second));
            cp[e.first.first][e.first.second] += e.second;
        }

        M = N;
        for(int i = 1; i <= N; i++) edg[i].clear();
        for(int i = 1; i <= N; i++)
            for(int j = i + 1; j <= N; j++)
                if(cp[i][j] || cp[j][i])
                {
                    edg[i].push_back(j);
                    edg[j].push_back(i);
                    if(cp[i][j] && cp[j][i])
                    {
                        int c = cp[j][i];
                        cp[j][i] = 0;
                        M++;
                        edg[i].push_back(M);
                        edg[j].push_back(M);
                        edg[M].push_back(i);
                        edg[M].push_back(j);
                        cp[j][M] = cp[M][i] = c;
                    }
                }
        N = M;
    }

    void BFS(int start)
    {
        for(int i = 1; i <= M; i++) d[i] = 0;
        d[start] = 1;
        queue <int> q;
        q.push(start);
        while(!q.empty())
        {
            int nod = q.front(); q.pop();
            for(auto nxt: edg[nod])
                if(!d[nxt] && cp[nod][nxt])
                {
                    d[nxt] = 1 + d[nod];
                    f[nxt] = nod;
                    q.push(nxt);
                }
        }
    }

    int getFlow(int nod)
    {
        if(nod == S)    return (1 << 30);
        int ans = min( cp[ f[nod] ][nod], getFlow(f[nod]) );
        return ans;
    }

    void pushFlow(int nod, int nxt, int flow)
    {
        cp[nod][nxt] -= flow;
        cp[nxt][nod] += flow;
        if(nod == S)    return;
        pushFlow(f[nod], nod, flow);
    }

    int getMaxFlow(int _S, int _T)
    {
        S = _S; T = _T;
        createGraph();

        int flow = 0;
        bool newFlow = true;
        while(newFlow)
        {
            newFlow = false;
            BFS(S);

            for(auto nod: edg[T])
                if(cp[nod][T])
                {
                    int addFlow = getFlow(nod);
                    addFlow = min(addFlow, cp[nod][T]);
                    if( addFlow )
                    {
                        pushFlow(nod, T, addFlow);
                        flow += addFlow;
                        newFlow = true;
                    }
                }
        }

        return flow;
    }
};

int main()
{
    #ifdef FILE_IO
    freopen("maxflow.in", "r", stdin);
    freopen("maxflow.out", "w", stdout);
    #endif

    EdmondsKarp maxFlow;

    int N, M;
    cin >> N >> M;
    for(int i = 1; i <= M; i++)
    {
        int x, y, c;
        cin >> x >> y >> c;
        maxFlow.addEdge(x, y, c);
    }

    int flow = maxFlow.getMaxFlow(1, N);
    printf("%d\n", flow);

    return 0;
}