Cod sursa(job #1145079)

Utilizator oprea1si2si3Oprea Sebastian oprea1si2si3 Data 17 martie 2014 21:02:58
Problema Flux maxim de cost minim Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 3.57 kb
#include<fstream>
#include<vector>
#define MAXN 360
#define INF (1<<27)
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;
    in>>NumarNoduri>>NumarMuchii>>Sursa>>Destinatie;
    for(i=1;i<=NumarMuchii;i++) {
        in>>x>>y>>Capacitate[x][y]>>Cost[x][y];
        Muchie[x].push_back(y);
        Muchie[y].push_back(x);
        Cost[y][x]=-Cost[x][y];
    }
    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 Down_Heap(int nod) {

    int fiu=1;
    while(fiu) {
        fiu=0;
        if(2*nod<=varf) {
            fiu=2*nod;
            if(2*nod+1<=varf && Distanta[Heap[2*nod]]<Distanta[Heap[2*nod+1]])
                fiu=2*nod+1;
            if(Distanta[Heap[nod]]<Distanta[Heap[fiu]])
                fiu=0;
        }
        if(fiu) {
            swap(Heap[nod],Heap[fiu]);
            swap(Poz[Heap[nod]],Poz[Heap[fiu]]);
            nod=fiu;
        }
    }
}

void Up_Heap(int nod) {

    while(nod>1 && Distanta[Heap[nod]]<Distanta[nod/2]) {
        swap(Heap[nod],Heap[nod/2]);
        swap(Poz[Heap[nod]],Poz[Heap[nod/2]]);
        nod=nod/2;
    }

}

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];
        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");
    out<<FluxMaximCostMinim<<'\n';
    out.close();

}

int main() {

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

}