Cod sursa(job #1334095)

Utilizator okros_alexandruOkros Alexandru okros_alexandru Data 3 februarie 2015 21:36:36
Problema Flux maxim de cost minim Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.75 kb
#include <fstream>
#include <vector>
#include <queue>

#define Nmax 352
#define oo (1 << 30)
#define neighbour Graph[node][i]

using namespace std;

vector <int> Graph[Nmax];
int N, minCost, Source, Destination, Cost[Nmax][Nmax], Capacity[Nmax][Nmax], Father[Nmax];
bool inQueue[Nmax];

class priorityQueue {

    #define root 1
    #define father (node >> 1)
    #define leftSon (node << 1)
    #define rightSon ((node << 1) | 1)
    #define compare(a, b) (A[Heap[a]] < A[Heap[b]])

    private:
        int size, Heap[Nmax], Location[Nmax];

    public:
        int A[Nmax];

        priorityQueue() {
            size = 0;
        }

        void insert(int index, int value) {
            A[index] = value;
            Heap[++size] = index;
            Location[index] = size;

            up(size);
        }

        void update(int index, int value) {
            A[index] = value;
            up(Location[index]);
        }

        void pop() {
            Heap[1] = Heap[size--];
            Location[Heap[1]] = 1;
            down(1);
        }

        inline int operator[](int index) {
            return A[index];
        }

        int front() {
            return Heap[1];
        }

        bool empty() {
            return (size == 0);
        }

    private:
        void up(int node) {

            while(node != root && compare(node, father)) {
                swap(Heap[node], Heap[father]);
                swap(Location[Heap[node]], Location[Heap[father]]);
                node = father;
            }
        }

        void down(int node) {

            int son;
            do {
                son = 0;

                if(leftSon <= size) {
                    son = leftSon;

                    if(rightSon <= size && compare(rightSon, son))
                        son = rightSon;

                    if(compare(node, son))
                        son = 0;
                }

                if(son != 0) {
                    swap(Heap[node], Heap[son]);
                    swap(Location[Heap[node]], Location[Heap[son]]);
                    node = son;
                }
            } while(son);
        }
} pq;

int BellmanFord() {

    int i, node;
    queue <int> Queue;

    for(i = 1; i <= N; i++)
        pq.A[i] = oo;

    pq.A[Source] = 0;
    Queue.push(Source);
    inQueue[Source] = true;

    while(!Queue.empty()) {

        node = Queue.front();
        Queue.pop();
        inQueue[node] = false;

        for(i = 0; i < Graph[node].size(); i++)
            if(Capacity[node][neighbour] > 0 && pq[neighbour] > pq[node] + Cost[node][neighbour]) {
                pq.A[neighbour] = pq[node] + Cost[node][neighbour];

                if(!inQueue[neighbour]) {
                    Queue.push(neighbour);
                    inQueue[neighbour] = true;
                }
            }
    }

    return pq[Destination];
}
bool Dijkstra() {

    int i, node;

    for(node = 1; node <= N; node++)
        for(i = 0; i < Graph[node].size(); i++)
            if(pq[node] != oo && pq[neighbour] != oo)
                Cost[node][neighbour] += pq[node] - pq[neighbour];

    for(node = 1; node <= N; node++)
        pq.insert(node, oo);

    pq.update(Source, 0);

    while(!pq.empty()) {

        node = pq.front();
        pq.pop();

        for(i = 0; i < Graph[node].size(); i++)
            if(Capacity[node][neighbour] > 0 && pq[neighbour] > pq[node] + Cost[node][neighbour]) {
                pq.update(neighbour, pq[node] + Cost[node][neighbour]);
                Father[neighbour] = node;
            }
    }

    return (pq[Destination] != oo);
}
void Solve() {

    int cost, node, maxFlow;

    cost = BellmanFord();

    while(Dijkstra()) {

        maxFlow = oo;

        for(node = Destination; node != Source; node = Father[node])
            maxFlow = min(maxFlow, Capacity[Father[node]][node]);

        for(node = Destination; node != Source; node = Father[node]) {
            Capacity[Father[node]][node] -= maxFlow;
            Capacity[node][Father[node]] += maxFlow;
        }

        cost += pq[Destination];
        minCost += maxFlow * cost;
    }

}
void Read() {

    int x, y, cost, capacity, M;
    ifstream in("fmcm.in");
    in >> N >> M >> Source >> Destination;

    while(M--) {
        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 << minCost << '\n';
    out.close();
}
int main() {

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

    return 0;
}