Cod sursa(job #2747641)

Utilizator MagnvsDaniel Constantin Anghel Magnvs Data 29 aprilie 2021 15:19:32
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.81 kb
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

const int inf = (1<<30)-1;
const int nmax = 350, fmax = 10000;

vector <int> g[nmax+1];
int f[nmax+1][nmax+1], c[nmax+1][nmax+1];

int d[nmax+1];
queue <int> q;

struct str{
    int x, y;
    str(int xnew, int ynew) {
        x = xnew;
        y = ynew;
    }
};

struct str_cmp{
    bool operator ()( str x, str y ) {
        return x.y > y.y;
    }
};

priority_queue <str, vector <str>, str_cmp> h;
int r[nmax+1];

int main( ) {
    int n, m, source, destination;
    fin >> n >> m >> source >> destination;
    for ( int i = 1; i <= m; ++ i ) {
        int x, y;
        fin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
        fin >> f[x][y] >> c[x][y];
        c[y][x] = -c[x][y];
    }

    for ( int i = 1; i <= n; ++ i ) {
        d[i] = inf;
    }
    d[source] = 0;
    q.push(source);
    while ( q.empty() == 0 ) {
        int x = q.front();
        q.pop();
        for ( int i = 0; i < int(g[x].size()); ++ i ) {
            int xn = g[x][i];
            if ( f[x][xn] > 0 && d[xn] > d[x]+c[x][xn] ) {
                d[xn] = d[x]+c[x][xn];
                q.push(xn);
            }
        }
    }

    int sol = 0, cd = 0;
    while ( d[destination] != inf ) {
        for ( int x = 1; x <= n; ++ x ) {
            for ( int i = 0; i < int(g[x].size()); ++ i ) {
                int xn = g[x][i];
                if ( d[x] != inf && d[xn] != inf ) {
                    c[x][xn] += d[x]-d[xn];
                }
            }
        }
        cd += d[destination];
        for ( int i = 1; i <= n; ++ i ) {
            d[i] = inf;
        }
        d[source] = 0;
        h.push(str(source,d[source]));

        while ( h.empty() == 0 ) {
            int x = h.top().x, y = h.top().y;
            h.pop();
            if ( d[x] == y ) {
                for ( int i = 0; i < int(g[x].size()); ++ i ) {
                    int xn = g[x][i];
                    if ( f[x][xn] > 0 && d[xn] > d[x]+c[x][xn] ) {
                        d[xn] = d[x]+c[x][xn];
                        r[xn] = x;
                        h.push(str(xn, d[xn]));
                    }
                }
            }
        }

        if ( d[destination] != inf ) {
            int aux = fmax;
            for ( int i = destination; i != source; i = r[i] ) {
                if ( aux > f[r[i]][i] ) {
                    aux = f[r[i]][i];
                }
            }
            for ( int i = destination; i != source; i = r[i] ) {
                f[r[i]][i] -= aux;
                f[i][r[i]] += aux;
            }
            sol += aux*(d[destination]+cd);
        }
    }

    fout << sol << "\n";

    return 0;
}