Cod sursa(job #2012235)

Utilizator EuAlexOtaku Hikikomori EuAlex Data 18 august 2017 12:55:51
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.56 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>
 
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];
bitset <1 + nmax> viz;
void dijkstra() {
    fill(distdij + 1, distdij + n + 1, inf);
    viz = 0;
    distdij[sursa] = 0;
 
    plusflow[sursa] = inf;
    pq.push({sursa, 0});
 
    while(!pq.empty()) {
        int from = pq.top().nod;
 
        if(viz[from] == 0) {
            viz[from] = 1;
            for(int k = 0; k < g[from].size(); ++ k) {
                Muchie e = g[from][k];
                if(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;
}