Cod sursa(job #1164048)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 1 aprilie 2014 20:19:34
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.85 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>
#include <cstring>
#include <fstream>

#define Nmax 355
#define INF 0x3f3f3f3f

using namespace std;

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

int N,M,S,D,nr = -1;
int old_dist[Nmax];
int real_dist[Nmax];
int dist[Nmax];
int daddy[Nmax];
int capacity[Nmax][Nmax];
int flow[Nmax][Nmax];
int cost[Nmax][Nmax];

vector<int> G[Nmax];
queue<int> Q;
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > Heap;
bitset<Nmax>inQ;

void read()
{
    fin>> N >> M >> S >> D;
    int a,b,c,z;
    for(int i = 1; i <= M; ++i)
    {
        fin >> a >> b >> c >> z;
        G[a].push_back(b);
        G[b].push_back(a);
        capacity[a][b] = c;
        cost[a][b] = z;
        cost[b][a] = -z;
    }
}


void get_old_dist()
{
    memset(old_dist,INF,sizeof(old_dist));
    old_dist[S] = 0;
    Q.push(S);
    int k;
    while(!Q.empty())
    {
        k = Q.front(); Q.pop();inQ[k] = 0;
        for(vector<int>::iterator it = G[k].begin(); it != G[k].end(); ++it)
            if(capacity[k][*it] - flow[k][*it] > 0 && old_dist[*it] > old_dist[k] + cost[k][*it])
            {
                old_dist[*it] = old_dist[k] + cost[k][*it];
                if(inQ[*it]) continue;
                inQ[*it] = 1;
                Q.push(*it);
            }
    }
}

int dijkstra()
{
    memset(dist,INF,sizeof(dist));
    memset(real_dist,INF,sizeof(real_dist));
    dist[S] = real_dist[S] = 0;
    Heap.push(make_pair(0,S));
    int k;
    while(!Heap.empty())
    {
        k = Heap.top().second;
        Heap.pop();
        if(k == D) continue;
        for(vector<int> ::iterator it = G[k].begin(); it != G[k].end(); ++it)
            if( capacity[k][*it] - flow[k][*it] != 0 &&
               dist[*it] > dist[k] + cost[k][*it] + old_dist[k] - old_dist[*it])
            {
                daddy[*it] = k;
                dist[*it] = dist[k] + cost[k][*it] + old_dist[k] - old_dist[*it];

                real_dist[*it] = real_dist[k] + cost[k][*it];
                Heap.push(make_pair(dist[*it],*it));
            }
    }
    for(int i = 1; i <= N; ++i)
        old_dist[i] = real_dist[i];
    return real_dist[D] != INF;
}

void FLOW()
{
    int minFLOW,minCOST = 0;
    while(dijkstra())
    {
        minFLOW = INF;
        for(int nodc = D; nodc != S; nodc = daddy[nodc])
            minFLOW = min(minFLOW,capacity[daddy[nodc]][nodc] - flow[daddy[nodc]][nodc]);
        for(int nodc = D; nodc != S; nodc = daddy[nodc])
        {
            flow[daddy[nodc]][nodc] += minFLOW;
            flow[nodc][daddy[nodc]] -= minFLOW;
        }
        minCOST += real_dist[D] * minFLOW;
    }
    fout << minCOST;
}

int main()
{

    read();
    get_old_dist();
    FLOW();

    return 0;
}