Cod sursa(job #1145184)

Utilizator oprea1si2si3Oprea Sebastian oprea1si2si3 Data 17 martie 2014 22:29:25
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 3.78 kb
#include<fstream>
#include<iostream>
#include<vector>
#define MAXN 400
#define INF (1<<27)

#define left(i) (2*i)
#define right(i) (2*i+1)
#define father(i) (i/2)
#define cmp(a,b) (Distanta[Heap[a]]<Distanta[Heap[b]])

using namespace std;

vector <int> Muchie[MAXN];
int NumarNoduri,NumarMuchii,Sursa,Destinatie,Capacitate[MAXN][MAXN],Cost[MAXN][MAXN];
int Tata[MAXN],Heap[MAXN],Poz[MAXN],Distanta[MAXN],varf;
int Flux,Suma,FluxMaximCostMinim;

void citire() {

    ifstream in("fmcm.in");
    int i,x,y,c,d;
    in>>NumarNoduri>>NumarMuchii>>Sursa>>Destinatie;
    for(i=1;i<=NumarMuchii;i++) {
        in>>x>>y>>c>>d;
        Capacitate[x][y]=c;
        Cost[x][y]=d;
        Muchie[x].push_back(y);
        Muchie[y].push_back(x);
        Cost[y][x]=-d;
    }
    in.close();

}

void BellmanFord() {

    int i,j,k;
    bool ok;
    for(i=1;i<=NumarNoduri;i++)
        Distanta[i]=INF;
    Distanta[Sursa]=0;
    ok=0;

    for(i=1;i<=NumarNoduri&&!ok;i++) {
        ok=1;
        for(j=1;j<=NumarNoduri;j++)
            for(k=0;k<Muchie[j].size();k++) {
                if(Capacitate[j][Muchie[j][k]] >0 && ((Distanta[j]+Cost[j][Muchie[j][k]])<Distanta[Muchie[j][k]]) ) {
                    ok=0;
                    Distanta[Muchie[j][k]]=Distanta[j]+Cost[j][Muchie[j][k]];
                }
            }
    }
    Suma=Distanta[Destinatie];
}


void Up_Heap(int nod) {

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

}
void Down_Heap(int nod) {

    int son;
    do {
        son=0;
        if(left(nod)<=varf) {
            son=left(nod);
            if(right(nod)<=varf&&cmp(right(nod),left(nod)))
                son=right(nod);
            if(cmp(nod,son))
                son=0;
            }
        if(son) {
            swap(Heap[nod],Heap[son]);
            swap(Poz[Heap[nod]],Poz[Heap[son]]);
            nod=son;
            }
    }while(son);

}
bool Dijkstra() {

    int i,j,nod,vecin;

    for(i=1;i<=NumarNoduri;i++)
        for(j=0;j<Muchie[i].size();j++)
            if((Distanta[i]!=INF) && (Distanta[Muchie[i][j]]!=INF))
                Cost[i][Muchie[i][j]]+=Distanta[i]-Distanta[Muchie[i][j]];



    for(i=1;i<=NumarNoduri;i++){
        Heap[i]=i;
        Poz[i]=i;
        Distanta[i]=INF;
    }
    Heap[Sursa]=1;
    Heap[1]=Sursa;
    Poz[Sursa]=1;
    Poz[1]=Sursa;
    Distanta[Sursa]=0;
    varf=NumarNoduri;
    nod=Heap[1];
    while(varf && Distanta[nod]!=INF) {
        nod=Heap[1];
        Heap[1]=Heap[varf];
        varf--;
        Poz[Heap[1]]=1;
        Down_Heap(1);
        for(i=0;i<Muchie[nod].size();i++) {
            vecin=Muchie[nod][i];
            if(Capacitate[nod][vecin]>0 && (Distanta[nod]+Cost[nod][vecin]<Distanta[vecin])){
                Distanta[vecin]=Distanta[nod]+Cost[nod][vecin];
                Tata[vecin]=nod;
                Up_Heap(Poz[vecin]);
            }
        }
    }
    if(Distanta[Destinatie]==INF)
        return 0;
    return 1;

}

void solve() {

    int i;
    Flux=0;
    FluxMaximCostMinim=0;
    BellmanFord();

    while(Dijkstra()) {
        Flux=INF;
        for(i=Destinatie;i!=Sursa;i=Tata[i]){
            Flux=min(Flux,Capacitate[Tata[i]][i]);
        }
        for(i=Destinatie;i!=Sursa;i=Tata[i]){
            Capacitate[Tata[i]][i]-=Flux;
            Capacitate[i][Tata[i]]+=Flux;
        }
        Suma+=Distanta[Destinatie];
        FluxMaximCostMinim+=Flux*Suma;
    }
}


void afisare() {

    ofstream out("fmcm.out");
    int i;
    out<<FluxMaximCostMinim<<'\n';
    out.close();

}

int main() {

    citire();
    solve();
    afisare();
    return 0;

}