Cod sursa(job #953763)

Utilizator ericptsStavarache Petru Eric ericpts Data 27 mai 2013 11:22:29
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 3.24 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <utility>
#include <set>
#include <queue>
#include <cstring>

#define pb push_back
#define mp make_pair

using namespace std;

const int MAX_N = 400;
const int INF = 0x7f7f7f7f;

vector< int > G[MAX_N];

int n,m;
int source,dest;
int dist[MAX_N];
int C[MAX_N][MAX_N];
int F[MAX_N][MAX_N];
int CST[MAX_N][MAX_N];
int best[MAX_N];
int actual[MAX_N];
int TT[MAX_N];
bool in_Q[MAX_N];

queue<int> Q;

struct comp{
public:
    bool operator()(const int &a,const int &b)
    {
        if(best[a] == best[b])
            return a < b;
        return best[a] < best[b];
    }
};

set< int , comp> T;

void bellman()
{
    memset(dist,0x7F,sizeof(dist));
    memset(in_Q,0,sizeof(in_Q));
    dist[source] = 0;
    int nod;
    Q.push(source);
    while(!Q.empty()){
        nod = Q.front();
        Q.pop();
        in_Q[nod] = 0;

        for(vector<int> :: iterator it = G[nod].begin() ; it != G[nod].end() ; ++ it){

            if(!C[nod][*it])continue;

            if(dist[nod] + CST[nod][*it] < dist[*it]){
                dist[*it] = dist[nod] + CST[nod][*it];
                if(!in_Q[*it]){
                    Q.push(*it);
                    in_Q[*it] = 1;
                }
            }
        }
    }

}

bool dij()
{
    memset(best,0x7f,sizeof(best));
    memset(actual,0x7f,sizeof(actual));
    memset(TT,0,sizeof(TT));
    memset(in_Q,0,sizeof(in_Q));

    int nod;
    T.insert(source);
    best[source] = 0;
    actual[source] = 0;
    while(!T.empty()){
        nod = *T.begin();T.erase(T.begin());
        in_Q[nod] = 0;

        for(vector<int> :: iterator it = G[nod].begin() ; it != G[nod].end() ; ++ it){
            if(F[nod][*it] == C[nod][*it])continue;
            if(best[nod] + CST[nod][*it] + dist[nod] - dist[*it] < best[*it]){
                if(in_Q[*it])
                    T.erase(T.find(*it));
                best[*it] = best[nod] + CST[nod][*it] + dist[nod] - dist[*it];
                actual[*it] = actual[nod] + CST[nod][*it];
                T.insert(*it);
                TT[*it] = nod;
            }

        }
    }

    if(best[dest] == INF)
        return 0;
    else return 1;
}

int flux,cost_flux;

void add_flow()
{
    int nod,f_min = INF;
    int tot = 0;
    for(nod = dest ; TT[nod] ; nod = TT[nod]){
        f_min = min(f_min , C[TT[nod]][nod] - F[TT[nod]][nod]);
        tot += CST[TT[nod]][nod];
    }

    flux += f_min;
    cost_flux += tot * f_min;

    for(nod = dest ; TT[nod] ; nod = TT[nod]){
        F[TT[nod]][nod] += f_min;
        F[nod][TT[nod]] -= f_min;
    }


    //memcpy(dist,actual,sizeof(best));

}

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

    scanf("%d %d %d %d",&n,&m,&source,&dest);

    int i,from,to,capacity,cost;

    for(i = 1 ; i <= m ; ++ i){
            scanf("%d %d %d %d",&from,&to,&capacity,&cost);
            C[from][to] += capacity;
            CST[from][to] = cost;
            CST[to][from] = -cost;
            G[from].pb(to);
            G[to].pb(from);
    }

    bellman();

    while(dij())
        add_flow();

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

}