Cod sursa(job #1580225)

Utilizator sebinechitasebi nechita sebinechita Data 25 ianuarie 2016 17:56:52
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.83 kb
#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define MAX 352
#define INF 1000000000
struct edge{
    int x, y, cost, flow;
    int cap;
};
queue <int> Q;
priority_queue <pair<int, int> > PQ;
typedef vector <int> :: iterator iter;
vector <int> G[MAX];
vector <edge> e;
int dist[MAX], inQ[MAX], n, d, dad[MAX], dade[MAX], di[MAX];

edge make_edge(int ix, int iy, int c, int f, int ca)
{
    edge e;
    e.x = ix;
    e.y = iy;
    e.cost = c;
    e.cap = ca;
    e.flow = f;
    return e;
}

void muchie(int x, int y, int cost, int cap)
{
    G[x].push_back(e.size());
    e.push_back(make_edge(x, y, cost, 0, cap));
    G[y].push_back(e.size());
    e.push_back(make_edge(y, x, -cost, 0, 0));
}

void bf(int nod)
{
    int i;
    Q.push(nod);
    for(i = 1 ; i <= n ; i++)
    {
        dist[i] = INF;
    }
    dist[nod] = 0;
    while(Q.size())
    {
        nod = Q.front();
        Q.pop();
        inQ[nod] = 0;
        for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
        {
            if(e[*it].flow != e[*it].cap && dist[e[*it].y] > dist[nod] + e[*it].cost)
            {
                dist[e[*it].y] = dist[nod] + e[*it].cost;
                if(!inQ[e[*it].y])
                {
                    Q.push(e[*it].y);
                    inQ[e[*it].y] = 1;
                }
            }
        }
    }
}

bool dijkstra(int nod)
{
    for(int i = 1 ; i <= n ; i++)
    {
        di[i] = INF;
    }
    di[nod] = 0;
    while(PQ.size())
        PQ.pop();
    PQ.push(make_pair(-di[nod], nod));
    while(PQ.size())
    {
        nod = PQ.top().second;
        PQ.pop();
        for(iter it = G[nod].begin() ; it != G[nod].end() ; it++)
        {
            if(e[*it].cap > e[*it].flow && di[e[*it].y] > di[nod] + e[*it].cost + dist[e[*it].x] - dist[e[*it].y])
            {
                di[e[*it].y] = di[nod] + e[*it].cost + dist[e[*it].x] - dist[e[*it].y];
                dad[e[*it].y] = nod;
                dade[e[*it].y] = *it;
                PQ.push(make_pair(-di[e[*it].y], e[*it].y));
            }
        }
    }
    return di[d] != INF;
}

int main()
{
    int m, s, x, i, y, c, ca, minim, maxflow = 0;
    fin >> n >> m >> s >> d;
    while(m--)
    {
        fin >> x >> y >> ca >> c;
        muchie(x, y, c, ca);
    }
    bf(s);
    while(dijkstra(s))
    {
        minim = INF;
        for(i = d ; dad[i] ; i = dad[i])
        {
            minim = min(minim, e[dade[i]].cap - e[dade[i]].flow);
        }
        for(i = d ; dad[i] ; i = dad[i])
        {
            maxflow += minim * e[dade[i]].cost;
            e[dade[i]].flow += minim;
            e[dade[i] ^ 1].flow -= minim;
        }
    }
    fout << maxflow << "\n";
}