Cod sursa(job #972459)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 11 iulie 2013 19:18:34
Problema Flux maxim de cost minim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include <fstream>
#include <vector>
#include <queue>
#include <bitset>
#include <cstring>

#define In "fmcm.in"
#define Out "fmcm.out"
#define Nmax 351
#define Inf 0x3f3f3f3f
#define PII pair<int,int>

using namespace std;

int source, destination, N, Sol;
int od[Nmax], nd[Nmax], rd[Nmax],Father[Nmax];
int cost[Nmax][Nmax], C[Nmax][Nmax];
bitset<Nmax>in_queue;
vector<int>Graph[Nmax];

inline void Read()
{
    int X, Y, c, f, M;
    ifstream fin(In);
    fin>> N >> M >> source >> destination;
    while(M--)
    {
        fin>> X >> Y >> f >> c;
        Graph[X].push_back(Y);
        Graph[Y].push_back(X);
        C[X][Y] = f;
        cost[X][Y] = c;
        cost[Y][X] = -c;
    }
    fin.close();
}

inline bool Dijkstra()
{
    priority_queue< PII ,vector< PII > , greater <PII> >Q;
    memset(nd,Inf,sizeof(nd));
    nd[source] = rd[source]  = 0;
    Q.push(make_pair(0,source));
    int curent,nc;
    vector<int>::iterator it;
    while(!Q.empty())
    {
        curent = Q.top().second;
        Q.pop();
        for(it=Graph[curent].begin();it!=Graph[curent].end();++it)
        {
            nc =nd[curent] + cost[curent][*it] + od[curent] - od[*it];
            if(C[curent][*it] && nd[*it] > nc)
            {
                nd[*it] = nc;
                rd[*it] = rd[curent]+cost[curent][*it];
                Father[*it] = curent;
                Q.push(make_pair(nd[*it],*it));
            }
        }
    }
    return (nd[destination]!=Inf);
}

inline void Solve()
{
    int t, _min;
    while(Dijkstra())
    {
        memcpy(od,rd,sizeof(od));
       for(_min = Inf,t = destination;t != source;t = Father[t])
            _min = min(_min,C[Father[t]][t]);
        Sol += _min*rd[destination];
        for(t = destination;t != source;t = Father[t])
        {
            C[Father[t]][t] -= _min;
            C[t][Father[t]] += _min;
        }
    }
}

inline void Bellman_Ford()
{
    queue<int>Q;
    Q.push(source);
    in_queue[source] = true;
    memset(od,Inf,sizeof(od));
    od[source] = 0;
    int curent;
    vector<int>::iterator it;
    while(!Q.empty())
    {
        curent = Q.front();
        Q.pop();
        for(it=Graph[curent].begin();it!=Graph[curent].end();++it)
            if(C[curent][*it] && od[*it]>od[curent]+cost[curent][*it]  &&  !in_queue[*it])
            {
                od[*it] = od[curent]+cost[curent][*it];
                in_queue[*it] = true;
                Q.push(*it);
            }
    }
}

inline void Write()
{
    ofstream g(Out);
    g<<Sol<<"\n";
    g.close();
}

int main()
{
    Read();
    Bellman_Ford();
    Solve();
    Write();
    return 0;
}