Cod sursa(job #2900910)

Utilizator iulianarsenoiuArsenoiu Iulian iulianarsenoiu Data 12 mai 2022 14:49:14
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.27 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("fmcm.in");
ofstream g("fmcm.out");

const int oo = 0x3f3f3f3f;

int n,m,s,d;

int t[1005],dist[1005];

bool sel[1005];

vector<int> G[1005];

int cost[1005][1005];
int c[1005][1005],F[1005][1005];

int d_in[1005];
int np[1005];

bool cmp(pair<int,int> &a, pair<int,int> &b)
{
    return a < b;
}

struct heap
{
    pair<int,int> h[100005];
    int Heap = 0;

    void HeapUp(int nod)
    {
        if(nod==1)
        {
            return;
        }
        if(cmp(h[nod/2],h[nod]))
        {
            swap(h[nod/2],h[nod]);
            HeapUp(nod/2);
        }
    }
    void HeapDown(int nod)
    {
        if(nod*2+1<=Heap)
        {
            if(!cmp(h[nod*2],h[nod*2+1]))
            {
                if(cmp(h[nod],h[nod*2]))
                {
                    swap(h[nod],h[nod*2]);
                    HeapDown(nod*2);
                }
            }
            else
            {
                if(cmp(h[nod],h[nod*2+1]))
                {
                    swap(h[nod],h[nod*2+1]);
                    HeapDown(nod*2+1);
                }
            }
            return;
        }
        if(nod*2<=Heap)
        {
            if(cmp(h[nod],h[nod*2]))
            {
                swap(h[nod],h[nod*2]);
                HeapDown(nod*2);
            }
        }
    }
    void Push(pair<int,int> x)
    {
        h[++Heap] = x;
        HeapUp(Heap);
    }
    void Pop()
    {
        swap(h[1],h[Heap]);
        --Heap;
        HeapDown(1);
    }
    bool Empty()
    {
        return (Heap==0);
    }
    pair<int,int> Top()
    {
        return h[1];
    }
};

heap h;

void Bellman(int s)
{
    queue<int> q;
    for(int i=1; i<=n; i++)
    {
        sel[i] = false;
        d_in[i] = oo;
    }
    q.push(s);
    sel[s] = true;
    d_in[s] = 0;
    while(!q.empty())
    {
        int nod = q.front();
        q.pop();
        sel[nod] = false;
        for(auto it : G[nod])
        {
            if(d_in[nod] + cost[nod][it] < d_in[it] && F[nod][it] < c[nod][it])
            {
                d_in[it] = d_in[nod] + cost[nod][it];
                if(!sel[it])
                {
                    q.push(it);
                    sel[it] = true;
                }
            }
        }
    }
}

bool Dijkstra(int s, int d)
{
    for(int i=1; i<=n; i++)
    {
        sel[i] = false;
        t[i] = -1;
        dist[i] = oo;
    }
    heap h;
    dist[s] = 0;
    h.Push({0,s});
    while(!h.Empty())
    {
        while(!h.Empty() && sel[h.Top().second])
        {
            h.Pop();
        }
        if(h.Empty())
        {
            break;
        }
        int nod = h.Top().second;
        h.Pop();
        sel[nod] = true;
        for(auto it : G[nod])
        {
            if(dist[nod] + cost[nod][it] + d_in[nod] - d_in[it] < dist[it] && F[nod][it]<c[nod][it])
            {
                dist[it] = dist[nod] + cost[nod][it] + d_in[nod] - d_in[it];
                np[it] = np[nod] + cost[nod][it];
                t[it] = nod;
                h.Push({dist[it],it});
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        d_in[i] = np[i];
    }
    return (t[d]!=-1);
}

int max_flow(int s, int d)
{
    int rez = 0;
    while(Dijkstra(s,d))
    {
        int nod = t[d];
        int dad = t[nod];
        int add = c[t[d]][d] - F[t[d]][d];
        while(nod!=s)
        {
            add = min(add,c[dad][nod] - F[dad][nod]);
            nod = dad;
            dad = t[nod];
        }
        rez += cost[t[d]][d] * add;
        F[t[d]][d] += add;
        nod = t[d];
        dad = t[nod];
        while(nod!=s)
        {
            F[dad][nod] += add;
            F[nod][dad] -= add;
            rez += cost[dad][nod] * add;
            nod = dad;
            dad = t[nod];
        }
    }
    return rez;
}

int main()
{
    f>>n>>m>>s>>d;
    for(int i=1; i<=m; i++)
    {
        int x,y,cap,cst;
        f>>x>>y>>cap>>cst;
        c[x][y] = cap;
        cost[x][y] = cst;
        cost[y][x] = -cst;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    Bellman(s);
    g<<max_flow(s,d)<<'\n';
    return 0;
}