Cod sursa(job #758099)

Utilizator BitOneSAlexandru BitOne Data 14 iunie 2012 13:24:21
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.55 kb
#include <queue>
#include <vector>
#include <fstream>
#include <cstdlib>

using namespace std;
typedef pair<int, int> pr;

const int oo=1<<29;
const int N_MAX=361;
const int bSize=(1<<14)|1;

vector<pr> G[N_MAX];
vector<pr>::iterator it, iend;
int S, bIndex, lHeap;
int C[N_MAX][N_MAX];//, F[N_MAX][N_MAX];
char buffer[bSize];
int f[N_MAX], d[N_MAX], H[N_MAX], P[N_MAX];



struct cmp {
    bool operator() (const int& x, const int& y) const {return d[x] > d[y];}
};
void BellmanFord(int start, int end, int N)
{
    int x;
    bool was[N_MAX];
    priority_queue<int, vector<int>, cmp> pQ;

    for(x=1; x <= N; ++x)
        d[x]=oo, was[x]=false;
    d[start]=0;
    for(pQ.push(start); !pQ.empty();)
    {
        x=pQ.top(); pQ.pop();
        was[x]=false;
        for(it=G[x].begin(), iend=G[x].end(); it < iend; ++it)
            if(d[it->first] > d[x] + it->second && C[x][it->first] > 0)// F[x][it->first])
            {
                d[it->first]=d[x]+it->second;
                if(false == was[it->first])
                {
                    pQ.push(it->first);
                    was[it->first]=true;
                }
            }
    }
    S=d[end];
}
inline void _swap(int& x, int& y) {int aux=x; x=y; y=aux;}
void DownHeap(int k)
{
    for(int son=k<<1; son <= lHeap; k=son, son<<=1)
    {
        if(son < lHeap && d[H[son]] > d[H[son+1]])
            ++son;
        if(d[H[k]] <= d[H[son]])
            return ;
        _swap(H[k], H[son]);
        P[H[k]]=k;
        P[H[son]]=son;
    }
}
void UpHeap(int k)
{
    for(int key=d[H[k]], f=k>>1; k > 1 && key < d[H[f]]; k=f, f>>=1)
    {
        _swap(H[k], H[f]);
        P[H[k]]=k;
        P[H[f]]=f;
    }
}
inline void push(int x)
{
    H[++lHeap]=x;
    P[x]=lHeap;
    UpHeap(lHeap);
}
inline int pop()
{
    int r=H[1];
    P[H[1]]=-1;
    H[1]=H[lHeap];
    P[H[1]]=1;
    --lHeap;
    DownHeap(1);
    return r;
}
bool findPath(int start, int end, int N)
{
    int x, i, j, M;

    for(i=1; i <= N; ++i)
        if(oo != d[i])
        {
            for(j=0, M=G[i].size(); j < M; ++j)
                if(oo != d[G[i][j].first])
                    G[i][j].second+=d[i] - d[G[i][j].first];
        }
    for(i=1; i <= N; ++i)
    {
        d[i]=oo;
        f[i]=-1;
        P[i]=0;
    }
    d[start]=0; f[start]=-2; lHeap=0;
    for(push(start); lHeap; )
    {
        x=pop();
        P[x]=-1;
        for(it=G[x].begin(), iend=G[x].end(); it < iend; ++it)
        {
            if(-1 == P[it->first] || C[x][it->first] <= 0)// F[x][it->first])
                continue;
            if(oo == d[it->first])
            {
                d[it->first]=it->second+d[x];
                f[it->first]=x;
                push(it->first);
            }
            else if(d[it->first] > it->second + d[x])// F[x.second][it->first])
                 {
                     d[it->first]=it->second+d[x];
                     f[it->first]=x;
                     UpHeap(P[it->first]);
                }
        }
    }
    S+=d[end];
    return -1 != f[end] && oo != d[end];
}
inline int _min(int x, int y) {return x <= y ? x : y;}
void Read(istream& in, int& x)
{
    if(-1 == bIndex)
    {
        in.read(buffer, bSize);
        bIndex=0;
    }
    bool sgn=false;
    while(buffer[bIndex] < '0' || buffer[bIndex] > '9')
    {
        if('-' == buffer[bIndex])
            sgn=true;
        if(++bIndex == bSize)
        {
            in.read(buffer, bSize);
            bIndex=0;
        }
    }
    for(x=0; buffer[bIndex] >= '0' && buffer[bIndex] <= '9'; )
    {
        x=x*10+buffer[bIndex]-'0';
        if(++bIndex == bSize)
        {
            in.read(buffer, bSize);
            bIndex=0;
        }
    }
    if(sgn)
        x*=-1;
}
int main()
{
    long long int sum;
    int N, M, s, e, x, y, c, cMin;
    ifstream in("fmcm.in");
    ofstream out("fmcm.out");

    for(Read(in, N), Read(in, M), Read(in, s), Read(in, e); M; --M)
    {
        Read(in, x); Read(in, y); Read(in, C[x][y]); Read(in, c);
        G[x].push_back(pr(y, c));
        G[y].push_back(pr(x, -c));
    }
    BellmanFord(s, e, N);
    for(sum=0; findPath(s, e, N); sum+=1LL*cMin*S)
    {
        cMin=oo;
        for(x=e; -2 != f[x]; x=f[x])
            cMin=_min(cMin, C[f[x]][x]);// - F[f[x]][x]);
        for(x=e; -2 != f[x]; x=f[x])
        {
            C[f[x]][x]-=cMin;
            C[x][f[x]]+=cMin;
            /*F[f[x]][x]+=cMin;
            F[x][f[x]]-=cMin;*/
        }
    }
    out<<sum<<'\n';
}