Cod sursa(job #3039788)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 28 martie 2023 21:10:56
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.14 kb
#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<bitset>
#include<cstring>
using namespace std;


constexpr int NMAX = 5e2;
const int INF = 1e9;

struct muchie
{
    int from,to,cap,cost,flow;
};

vector<int> vecini[NMAX]; vector<muchie> muchii;
vector<int> dist,t,pi; int real[NMAX];
bitset<NMAX> inq;

void bf(int s,int e)
{
    fill(pi.begin(),pi.end(),INF); pi[s] = 0;
    queue<int> q; q.push(s); inq[s] = 1;
    while(!q.empty())
        {

            int v = q.front(); q.pop(); inq[v] = 0;
            for(auto it : vecini[v])
                {
                    if((muchii[it].cap - muchii[it].flow) <= 0) continue;
                    if(pi[muchii[it].to] > pi[v] + muchii[it].cost)
                        {
                            pi[muchii[it].to] = pi[v] + muchii[it].cost;
                            if(!inq[muchii[it].to])
                                {
                                    inq[muchii[it].to] = 1;
                                    q.push(muchii[it].to);
                                }
                        }

                }
        }

    exit(0);
}

struct miau
{
    int w; bool operator <(const miau &lhs) const
    {
        return dist[lhs.w] > dist[w];
    }
};

bool dijkstra(int s,int e)
{
    fill(dist.begin(),dist.end(),INF); dist[s] = 0; fill(t.begin(),t.end(),-1);
    priority_queue<miau> pq; pq.push({s}); real[s] = 0;
    while(!pq.empty())
        {
            int v = pq.top().w; pq.pop();
            for(auto it : vecini[v])
                {

                    muchie &h = muchii[it];
                    if((h.cap - h.flow) > 0)
                        {
                            int false_cost = dist[v] + h.cost + pi[v] - pi[h.to];
                            if(false_cost < 0) exit(1);
                            if(false_cost < dist[h.to])
                                {
                                    real[h.to] = real[v] + h.cost;
                                    dist[h.to] = false_cost;
                                    pq.push({h.to}); t[h.to] = it;
                                }
                        }
                }
        }

    return (dist[e] != INF);
}

int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);

    int n,m,s,e,a,b,c,d; cin >> n >> m >> s >> e;
    for(int i = 0; i < m ; i++)
        {
            cin >> a >> b >> c >> d;
            muchii.push_back({a,b,c,d,0}); vecini[a].emplace_back(2 * i);
            muchii.push_back({b,a,0,-d,0}); vecini[b].emplace_back(2 * i + 1);
        }

    long long ans = 0,flux = 0; dist.resize(n + 1); t.resize(n + 1); pi.resize(n + 1); bf(s,e);
    while(dijkstra(s,e))
        {
            int delta = INF;
            for(int v = t[e]; v != -1 ; v = t[muchii[v].from]) delta = min(delta,muchii[v].cap - muchii[v].flow);
            for(int v = t[e]; v != -1 ; v = t[muchii[v].from]) muchii[v].flow += delta,muchii[v ^ 1].flow -= delta;
            ans += 1LL * delta * real[e];
            for(int i = 1; i <= n ; i++) pi[i] = real[i];
        }


    cout << ans;
}