Cod sursa(job #952603)

Utilizator primulDarie Sergiu primul Data 23 mai 2013 18:52:21
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 6.3 kb
#include <fstream>
#include <vector>
#include <queue>
#define nmax 360
#define oo (1<<30)
#define Neighbor Graph[Node][i]
using namespace std;
 
vector <int> Graph[nmax];
int N, M, Source, Sink, CostMaxFlow, Distance[nmax];
int Capacity[nmax][nmax], Cost[nmax][nmax], Father[nmax];
bool inQueue[nmax];
 
class heap {
     
    #define hmax nmax;
    #define father(node) (node>>1)
    #define leftSon(node) (node<<1)
    #define rightSon(node) ((node<<1)|1)
    #define compare(a, b) ( Distance[H[a]] < Distance[H[b]] )
    #define compareMin(a, b) compare(a, b)
    #define comapreMax(a, b) compare(b, a)
     
    public:
        int Top,H[nmax],Index[nmax];
         
    public:
         
        heap() {
             
            Top = 0;
             
            }
         
        void precolate(int Node) {
             
            while( Node > 1 && compareMin(Node, father(Node)) ) {
                 
                swap(H[Node], H[father(Node)]);
                swap(Index[H[Node]], Index[H[father(Node)]]);
                Node = father(Node);
                 
                }
             
        }
         
        void sift(int Node) {
             
            int Son;
             
            do {
                 
                Son = 0;
                 
                if( leftSon(Node) <= this -> size() ) {
                     
                    Son = leftSon(Node);
                     
                    if( rightSon(Node) <= this -> size() && compareMin(rightSon(Node), Son) )
                        Son = rightSon(Node);
                     
                    if( compareMin(Node, Son) )
                        Son = 0;
                     
                    }
                 
                if( Son ) {
                     
                    swap(H[Node], H[Son]);
                    swap(Index[H[Node]], Index[H[Son]]);
                    Node = Son;
                     
                    }
                 
            } while( Son );
             
        }
         
        void push(int Node, int Value) {
             
            H[ ++Top ] = Node;
            Index[Node] = Top;
            Distance[Node] = Value;
            this -> precolate(Top);
             
            }
         
        void pop() {
             
            H[1] = H[ Top-- ];
            this -> sift(1);
             
            }
         
        void update(int Node, int Value) {
             
            int Aux = Distance[Node];
             
            Distance[Node] = Value;
             
            if( Aux > Distance[Node] )
                this -> precolate( Index[Node] );
            else
                this -> sift( Index[Node] );
             
            }
         
        int size() {
             
            return Top;
             
            }
         
        bool empty() {
             
            return ( Top == 0);
             
            }
         
        int top() {
             
            return H[1];
             
            }
     
};
 
void InitialiseDijkstra() {
     
    int i, Node;
     
    for(Node = 1; Node <= N; Node++)
        for(i = 0; i < Graph[Node].size(); i++)
            if( Distance[Node] != oo && Distance[Neighbor] != oo )
                Cost[Node][Neighbor] += Distance[Node] - Distance[Neighbor];
     
}
bool Dijkstra(int Source, int Sink) {
     
    int i, Node;
    heap Heap;
     
    InitialiseDijkstra();
     
    for(Node = 1; Node <= N; Node++)
        Heap.push(Node, oo);
     
    Heap.update(Source, 0);
     
    while( !Heap.empty() ) {
         
        Node = Heap.top();
        Heap.pop();
         
        for(i = 0; i < Graph[Node].size(); i++)
            if( Capacity[Node][Neighbor] > 0 && Distance[Neighbor] > Distance[Node] + Cost[Node][Neighbor] ) {
                 
                Father[Neighbor] = Node;
                Heap.update(Neighbor, Distance[Node] + Cost[Node][Neighbor] );
                 
                }
             
        }
     
    return ( Distance[Sink] != oo );
     
}
int BellmanFord(int Source, int Sink) {
     
    int i, Node;
    queue <int> Queue;
     
    for(i = 1; i <= N; i++)
        Distance[i] = oo;
     
    Queue.push(Source);
    Distance[Source] = 0;
     
    while(!Queue.empty()) {
         
        Node = Queue.front();
        Queue.pop();
        inQueue[Node] = false;
         
        for(i = 0; i < Graph[Node].size(); i++)
            if( Capacity[Node][Neighbor] > 0 && Distance[Neighbor] > Distance[Node] + Cost[Node][Neighbor] ) {
                 
                Distance[Neighbor] = Distance[Node] + Cost[Node][Neighbor];
                 
                if( !inQueue[Neighbor] ) {
                     
                    Queue.push(Neighbor);
                    inQueue[Neighbor] = true;
                     
                    }
             
            }
         
        }
     
    return Distance[Sink];
     
}
void Solve() {
     
    int i, Sum, maxFlow, Node;
     
    Sum = BellmanFord(Source, Sink);
     
    while( Dijkstra(Source, Sink) ) {
         
        maxFlow = oo;
         
        for(Node = Sink; Node != Source; Node = Father[Node])
            maxFlow = min(maxFlow, Capacity[Father[Node]][Node]);
         
        for(Node = Sink; Node != Source; Node = Father[Node]) {
             
            Capacity[Father[Node]][Node] -= maxFlow;
            Capacity[Node][Father[Node]] += maxFlow;
             
            }
         
        Sum += Distance[Sink];
         
        CostMaxFlow += Sum * maxFlow;
         
        }
     
}
void Read() {
     
    int i, x, y, capacity, cost;
    ifstream in("fmcm.in");
    in>>N>>M>>Source>>Sink;
     
    for(i = 1; i <= M; i++) {
         
        in>>x>>y>>capacity>>cost;
        Graph[x].push_back(y);
        Graph[y].push_back(x);
        Cost[x][y] = cost;
        Cost[y][x] = -cost;
        Capacity[x][y] = capacity;
         
        }
     
    in.close();
 
}
void Write() {
     
    ofstream out("fmcm.out");
    out<<CostMaxFlow<<'\n';
    out.close();
     
}
int main() {
     
    Read();
    Solve();
    Write();
     
    return 0;
     
}