Cod sursa(job #2111770)

Utilizator Mihai_PredaPreda Mihai Dragos Mihai_Preda Data 22 ianuarie 2018 17:48:46
Problema Flux maxim de cost minim Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.76 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>

using namespace std;

const int INF = (1 << 29);

class flow
{
public:
    flow(int n)
    {
        this->n = n;
        vecini.resize(n + 1);
        cap.resize(n + 1, vector<int>(n + 1));
        cost.resize(n + 1, vector<int>(n + 1));
    }
    void AddEdge(int x, int y, int capacity, int cost)
    {
        vecini[x].push_back(y);
        vecini[y].push_back(x);
        cap[x][y] = capacity;
        this->cost[x][y] = cost;
        this->cost[y][x] = -cost;
    }
    long long GetMinCostMaxFlow(int source, int dest)
    {
        long long ret = 0;
        vector<vector<int> > flux(n+1, vector<int>(n+1));
        vector<int> father(n+1);
        while(BellmanFord(source, dest, flux, father))
        {
            int mn = INF;
            for(int nod = dest; nod != source; nod = father[nod])
                mn = min(mn, cap[father[nod]][nod] - flux[father[nod]][nod]);
            for(int nod = dest; nod != source; nod = father[nod])
            {
                ret += 1LL * cost[father[nod]][nod] * mn;
                flux[father[nod]][nod] += mn;
                flux[nod][father[nod]] -= mn;
            }
        }
        return ret;
    }
private:
    bool BellmanFord(int source, int dest, vector<vector<int> > &flux, vector<int> &father)
    {
        bool ret = false;
        vector<int> dp(n+1, INF);
        vector<bool> viz(n+1);
        queue<int> q;
        q.push(source);
        dp[source] = 0;
        viz[source] = true;
        int nod;
        while(q.empty() == false)
        {
            nod = q.front();
            q.pop();
            if(nod == dest)
                ret = true;
            viz[nod] = false;
            for(auto v:vecini[nod])
            {
                if(cap[nod][v] == flux[nod][v])
                    continue;
                if(dp[nod] + cost[nod][v] < dp[v])
                {
                    dp[v] = dp[nod] + cost[nod][v];
                    father[v] = nod;
                    if(viz[v] == false)
                    {
                        q.push(v);
                        viz[v] = true;
                    }
                }
            }
        }
        return ret;
    }
    int n;
    vector<vector<int> > vecini;
    vector<vector<int> > cap;
    vector<vector<int> > cost;

};

int main()
{
    ifstream in("fmcm.in");
    int n, m, s, d;
    in >> n >> m >> s >> d;
    flow gr(n);
    int x, y, c, z;
    while(m--)
    {
        in >> x >> y >> c >> z;
        gr.AddEdge(x, y, c, z);
    }
    in.close();
    long long rasp = gr.GetMinCostMaxFlow(s, d);
    ofstream out("fmcm.out");
    out << rasp;
    out.close();
    return 0;
}