Cod sursa(job #1213924)

Utilizator abel1090Abel Putovits abel1090 Data 29 iulie 2014 11:20:58
Problema Flux maxim Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
///MAXFLOW
#include <iostream>
#include <fstream>
#include <vector>
#include <limits>
#include <queue>
#include <list>

using namespace std;

const unsigned INF = numeric_limits<unsigned>::max();

struct Node {
    short node, from;
    unsigned capacity;

    Node(short node, unsigned capacity, short from) {
        this->node = node;
        this->capacity = capacity;
        this->from = from;
    }
};

class CompareNodes {
public:
    bool operator ()(Node& a, Node& b) { return a.capacity < b.capacity; }
};

unsigned getAugmentedPath(vector<list<short> >& adjList,  ///PFS
                vector<vector<unsigned> >& capacity) {
    unsigned augmentedPath = 0;
    short sink = adjList.size() - 1;
    vector<bool> seen(sink + 1, false);
    vector<short> previous(sink + 1, -1);
    priority_queue<Node, vector<Node>, CompareNodes> pQueue;

    pQueue.push(Node(0, INF, -1));
    list<short>::iterator it;
    short current;
    unsigned currentCapacity;
    while(!pQueue.empty()) {
        current = pQueue.top().node;
        currentCapacity = pQueue.top().capacity;
        previous[current] = pQueue.top().from;
        pQueue.pop();

        seen[current] = true;

        if(current == sink) {
            augmentedPath = currentCapacity;
            break;
        }

        for(it = adjList[current].begin(); it != adjList[current].end(); it++)
            if(!seen[*it] && capacity[current][*it] > 0)
                pQueue.push(Node(*it, min(capacity[current][*it],
                                    currentCapacity), current));
    }

    sink = adjList.size() - 1;
    short from;
    while(previous[sink] > -1) {
        from = previous[sink];
        capacity[from][sink] -= augmentedPath;
        capacity[sink][from] += augmentedPath;
        sink = from;
    }

    return augmentedPath;
}

unsigned getMaxFlow(vector<list<short> >& adjList,
                vector<vector<unsigned> >& capacity) {
    unsigned maxFlow = 0, newPath;

    while(true) {
        newPath = getAugmentedPath(adjList, capacity);
        if(newPath == 0)
            break;
        maxFlow += newPath;
    }

    return maxFlow;
}

int main() {
    ifstream inStr("maxflow.in");
    ofstream outStr("maxflow.out");

    short numNodes, numEdges;

    inStr >> numNodes >> numEdges;

    vector<vector<unsigned> > capacity(numNodes, vector<unsigned>(numNodes, 0));
    vector<list<short> > adjList(numNodes);

    short from, to;
    unsigned cap;
    for(short i=0; i < numEdges; i++) {
        inStr >> from >> to >> cap;
        adjList[--from].push_back(--to);
        adjList[to].push_back(from);
        capacity[from][to] = cap;
    }

    outStr << getMaxFlow(adjList, capacity) << '\n';

    return 0;
}