Cod sursa(job #869015)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 31 ianuarie 2013 20:59:27
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.43 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();
     
}