Cod sursa(job #2966031)

Utilizator user12345user user user user12345 Data 16 ianuarie 2023 17:54:49
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.59 kb
#include <bits/stdc++.h> 
using namespace std;

ifstream fin("fmcm.in");
ofstream fout("fmcm.out");

template<class obj>
class heap {
private:

    struct nod {
        obj val;
        nod* down, * next;

        nod(obj val) {
            this->val = val;
            down = next = NULL;
        }
    };

    nod* root;

    inline nod* unit(nod* a, nod* b) {
        if (a == NULL)
            return b;

        if (b == NULL)
            return a;

        if (!(a->val < b->val))
            swap(a, b);

        b->next = a->down;
        a->down = b;

        return a;
    }

    inline nod* convert(nod* x) {
        if (x == NULL || x->next == NULL)
            return x;

        nod* next1 = x->next;
        nod* next2 = next1->next;

        return unit(unit(x, next1), convert(next2));
    }

public:

    inline heap() {
        root = NULL;
    }

    inline void add(obj val) {
        root = unit(root, new nod(val));
    }

    inline obj top() {
        return root->val;
    }

    inline bool empty() {
        return root == NULL;
    }

    inline void pop() {
        root = convert(root->down);
    }

    inline void clear() {
        root = NULL;
    }
};

int d[351];

struct nod {
    short x;

    bool operator < (nod& aux) {
        return d[x] < d[aux.x];
    }
};

heap <nod> H;

typedef long long ll;

vector <int> g[351];
int cost[351][351], flow[351][351], aux[351], t[351];
const int inf = 1000000000;
int n, m, src, dest;
bitset <351> inQ;

// Bellman-Ford
void generate()
{
    for (int i = 1; i <= n; i++)
        aux[i] = inf;

    aux[src] = 0;
    queue <int> Q;
    Q.push(src);
    inQ[src] = true;

    while (!Q.empty())
    {
        int nod = Q.front();
        Q.pop();
        inQ[nod] = false;

        for (auto& i : g[nod])
            if (flow[nod][i] && aux[i] > aux[nod] + cost[nod][i])
            {
                aux[i] = aux[nod] + cost[nod][i];
                Q.push(i);
                if (!inQ[i])
                    inQ[i] = true;
            }
    }
}

// dijkstra
inline bool djk()
{
    H.clear();

    memset(d, 0x3f3f3f3f, sizeof(d));

    d[src] = 0;
    H.add({ (short)src });
    int val, x;

    while (!H.empty())
    {
        x = H.top().x;
        H.pop();

        if (x == dest)
            return true;

        for (vector <int>::iterator i = g[x].begin(); i != g[x].end(); i++)
        {
            val = d[x] + cost[x][*i] + aux[x] - aux[*i];
            if (flow[x][*i] && d[*i] > val)
            {
                d[*i] = val;
                H.add({ (short)*i });
                t[*i] = x;
            }
        }
    }

    return false;
}

// minim cost for maxim flow
inline int minCost()
{
    int res = 0;

    while (djk())
    {
        int x = dest;
        int mini = inf;

        while (x != src)
        {
            if (flow[t[x]][x] < mini)
                mini = flow[t[x]][x];
            x = t[x];
        }

        res += (d[dest] + aux[dest]) * mini;
        x = dest;

        while (x != src)
        {
            flow[t[x]][x] -= mini;
            flow[x][t[x]] += mini;
            x = t[x];
        }
    }

    return res;
}

int main()
{
    fin >> n >> m >> src >> dest;

    for (int i = 1; i <= m; i++)
    {
        int x, y;
        fin >> x >> y;
        fin >> flow[x][y] >> cost[x][y];
        cost[y][x] = -cost[x][y];

        g[x].push_back(y);
        g[y].push_back(x);
    }

    generate();
    fout << minCost();

    return 0;
}