Cod sursa(job #934945)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 31 martie 2013 22:57:04
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.29 kb
#include <fstream>
#include <queue>
#include <vector>
#define nmax 356
#define oo (1<<30)
#define Vecin first
#define Cost second
using namespace std;

vector < pair<int,int> > G[nmax];
queue <int> Q;
int N,Start,Destination,nrinQ[nmax];
int maxflow,Sum,T[nmax],Flux[nmax][nmax];
bool inQ[nmax];

class HEAP {

    #define NMAxHeap nmax
    #define left(i) (2*i)
    #define right(i) (2*i+1)
    #define father(i) (i/2)
    #define cmp(a,b) (Dist[V[a]]<Dist[V[b]])

    private:
        int V[NMAxHeap],Loc[NMAxHeap],Vf;
    public:
        int Dist[NMAxHeap];
    public:
        HEAP():Vf(0){}
        void push(int,int);
        void pop();
        void update(int,int);
        int top();
        int size();
    private:
        void Up(int);
        void Down(int);

};
void HEAP::Up(int nod) {

    while(nod>1&&cmp(nod,father(nod))) {
        swap(V[nod],V[father(nod)]);
        swap(Loc[V[nod]],Loc[V[father(nod)]]);
        nod=father(nod);
        }

}
void HEAP::Down(int nod) {

    int son;
    do {
        son=0;
        if(left(nod)<=Vf) {

            son=left(nod);
            if(right(nod)<=Vf&&cmp(right(nod),son))
                son=right(nod);

            if(cmp(nod,son))
                son=0;
            }

        if(son) {
            swap(V[nod],V[son]);
            swap(Loc[V[nod]],Loc[V[son]]);
            nod=son;
            }

    }while(son);

}
void HEAP::push(int id,int Val) {

    V[++Vf]=id;
    Dist[id]=Val;
    Loc[id]=Vf;
    this->Up(Vf);

}
void HEAP::pop() {

    V[1]=V[Vf--];
    Loc[V[1]]=1;
    this->Down(1);

}
void HEAP::update(int id,int Val) {

    Dist[id]=Val;
    this->Up(Loc[id]);
    this->Down(Loc[id]);

}
int HEAP::top() {

    return V[1];

}
int HEAP::size() {

    return Vf;

}

HEAP Heap;

bool Dijkstra() {

    int i,j,Nod;

    for(i=1;i<=N;i++)
        for(j=0;j<G[i].size();j++)
            if(Heap.Dist[i]!=oo && Heap.Dist[G[i][j].Vecin]!=oo)
                G[i][j].Cost+=Heap.Dist[i]-Heap.Dist[G[i][j].Vecin];

    Heap.push(Start,0);
    for(i=1;i<=N;i++)
        if(i!=Start)
            Heap.push(i,oo);

    while(Heap.size()) {

        Nod=Heap.top();
        Heap.pop();

        for(i=0;i<G[Nod].size();i++)
            if(Flux[Nod][G[Nod][i].Vecin]>0 &&  Heap.Dist[Nod] + G[Nod][i].Cost < Heap.Dist[G[Nod][i].Vecin] ) {
                T[G[Nod][i].Vecin]=Nod;
                Heap.update(G[Nod][i].Vecin, Heap.Dist[Nod] + G[Nod][i].Cost);
                }

        }

    return (Heap.Dist[Destination]!=oo);

}
void BellmanFord(int Start) {

    int i,Nod;

    for(i=1;i<=N;i++)
        Heap.Dist[i]=oo;

    Q.push(Start);
    Heap.Dist[Start]=0;

    while(!Q.empty()) {

        Nod=Q.front();
        inQ[Nod]=0;
        Q.pop();

        for(i=0;i<G[Nod].size();i++)
            if(Flux[Nod][G[Nod][i].Vecin]>0 && Heap.Dist[Nod]+G[Nod][i].Cost<Heap.Dist[G[Nod][i].Vecin]) {

                Heap.Dist[G[Nod][i].Vecin]=Heap.Dist[Nod]+G[Nod][i].Cost;

                if(!inQ[G[Nod][i].Vecin]) {

                    Q.push(G[Nod][i].Vecin);
                    inQ[G[Nod][i].Vecin]=1;
                    nrinQ[G[Nod][i].Vecin]++;

                    if(nrinQ[G[Nod][i].Vecin]>=N)
                        return;

                    }

                }

        }

    Sum=Heap.Dist[Destination];

}
void Solve() {

    int flux,e,nod;

    BellmanFord(Start);

    while(Dijkstra()) {

        flux=oo;
        e=0;
        for(nod=Destination;nod!=Start;nod=T[nod],e++)
            flux=min(flux,Flux[T[nod]][nod]);

        for(nod=Destination;nod!=Start;nod=T[nod]) {
            Flux[T[nod]][nod]-=flux;
            Flux[nod][T[nod]]+=flux;
            }

        Sum+=Heap.Dist[Destination];
        maxflow+=flux*Sum;

        }

}
void Read() {

    int x,y,f,c,M;
    ifstream in("fmcm.in");
    in>>N>>M>>Start>>Destination;

    while(M--) {
        in>>x>>y>>f>>c;
        Flux[x][y]=f;
        G[x].push_back(make_pair(y,c));
        G[y].push_back(make_pair(x,-c));
        }

    in.close();

}
void Write() {

    ofstream out("fmcm.out");
    out<<maxflow<<'\n';
    out.close();

}
int main() {

    Read();
    Solve();
    Write();

}