Cod sursa(job #2012215)

Utilizator EuAlexOtaku Hikikomori EuAlex Data 18 august 2017 12:29:37
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.87 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>

using namespace std;

const int nmax = 350;
const int inf = 2000000000;

struct Muchie {
    int to, rev, flow, cap, cost;
};

int n, m, sursa, drena;
vector <Muchie> g[1 + nmax];

queue<int> q;
int dist[1 + nmax];
void bellmanford() {
    fill(dist + 1, dist + n + 1, inf);
    dist[sursa] = 0;
    q.push(sursa);

    while(!q.empty()) {
        int from = q.front();
        for(int k = 0; k < g[from].size(); ++ k) {
            Muchie e = g[from][k];
            if(e.flow < e.cap && dist[e.to] > dist[from] + e.cost) {
                dist[e.to] = dist[from] + e.cost;
                q.push(e.to);
            }
        }

        q.pop();
    }
}

struct Nod {
    int nod, cost;
    bool operator> (Nod other) const {
        return (cost > other.cost);
    }
};

priority_queue<Nod, vector<Nod>, greater<Nod> > pq;
int prevnod[1 + nmax], prevmuchie[1 + nmax], plusflow[1 + nmax], distdij[1 + nmax];
bool viz[1 + nmax];
void dijkstra() {
    fill(distdij + 1, distdij + n + 1, inf);
    fill(viz + 1, viz + n + 1, 0);
    distdij[sursa] = 0;

    plusflow[sursa] = inf;
    pq.push({sursa, 0});

    while(!pq.empty()) {
        int from = pq.top().nod;
        viz[from] = 1;
        for(int k = 0; k < g[from].size(); ++ k) {
            Muchie e = g[from][k];
            if(viz[e.to] == 0 && e.flow < e.cap && distdij[e.to] > distdij[from] + e.cost + dist[from] - dist[e.to]) {
                distdij[e.to] = distdij[from] + e.cost + dist[from] - dist[e.to];
                pq.push({e.to, distdij[e.to]});

                prevnod[e.to] = from;
                prevmuchie[e.to] = k;
                plusflow[e.to] = min(plusflow[from], e.cap - e.flow);
            }
        }

        pq.pop();
    }
}

int mincostflow() {
    int flow = 0, flowcostmin = 0;
    bellmanford();

    dijkstra();
    while(distdij[drena] < inf){
        int deltaflow = plusflow[drena];
        flow += deltaflow;

        for(int to = drena; to != sursa; to = prevnod[to]) {
            Muchie &e = g[prevnod[to]][prevmuchie[to]];
            e.flow += deltaflow;
            g[e.to][e.rev].flow -= deltaflow;
            flowcostmin += deltaflow * e.cost;
        }

        for(int i = 1; i <= n; ++ i) {
            dist[i] += distdij[i];
        }

        dijkstra();
    }

    return flowcostmin;
}

int main() {
    freopen("fmcm.in", "r", stdin);
    freopen("fmcm.out", "w", stdout);

    scanf("%d%d%d%d", &n, &m, &sursa, &drena);

    for(int i = 1; i <= m; ++ i) {
        int from, to, cap, cost;
        scanf("%d%d%d%d", &from, &to, &cap, &cost);
        g[from].push_back({to, g[to].size(), 0, cap, cost});
        g[to].push_back({from, g[from].size() - 1, 0, 0, -cost});
    }

    printf("%d\n", mincostflow());

    return 0;
}