Cod sursa(job #3226952)

Utilizator alexddAlexandru Dima alexdd Data 23 aprilie 2024 13:20:56
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.39 kb
#include<bits/stdc++.h>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
#define int long long
const int INF = 1e18;
int n,m;
struct edge
{
    int from,to;
    int cap;
    int cost;
};
vector<edge> edges;
vector<int> con[355];
int pi[355];
int prec[355];
int dist[355];
void add_edge(int from, int to, int cap, int cost)
{
    con[from].push_back(edges.size()); edges.push_back({from,to,cap,cost});
    con[to].push_back(edges.size()); edges.push_back({to,from,0,-cost});
}
bool get_path(int src, int dest)
{
    for(int i=1;i<=n;i++)
        dist[i]=INF;
    dist[src]=0;
    priority_queue<pair<int,int>> pq;
    pq.push({0,src});
    while(!pq.empty())
    {
        int nod = pq.top().second;
        int cdist = -pq.top().first;
        pq.pop();
        if(dist[nod]!=cdist)
            continue;
        for(auto e_id:con[nod])
        {
            edge e = edges[e_id];
            int val = dist[nod] + pi[nod] - pi[e.to] + e.cost;
            if(e.cap>0 && dist[e.to] > val)
            {
                dist[e.to] = val;
                prec[e.to] = e_id;
                pq.push({-dist[e.to],e.to});
            }
        }
    }
    if(dist[dest]<INF)
        return 1;
    return 0;
}
pair<int,int> maxflow_mincost(int src, int dest)
{
    int flow=0,cost=0;
    for(int i=1;i<=n;i++)
        pi[i]=INF;
    pi[src]=0;
    for(int pas=1;pas<=n;pas++)
        for(auto e:edges)
            if(e.cap>0)
                pi[e.to] = min(pi[e.to], pi[e.from]+e.cost);
    while(get_path(src,dest))
    {
        for(int i=1;i<=n;i++)
            pi[i] += dist[i];
        int mnm=INF,cur=dest,sumcost=0;
        while(cur!=src)
        {
            mnm = min(mnm, edges[prec[cur]].cap);
            sumcost += edges[prec[cur]].cost;
            cur = edges[prec[cur]].from;
        }
        flow += mnm;
        cost += sumcost*mnm;
        cur=dest;
        while(cur!=src)
        {
            edges[prec[cur]].cap -= mnm;
            edges[prec[cur]^1].cap += mnm;
            cur = edges[prec[cur]].from;
        }
    }
    return {flow,cost};
}

signed main()
{
    int src,dest;
    fin>>n>>m>>src>>dest;
    int x,y,c,z;
    for(int i=0;i<m;i++)
    {
        fin>>x>>y>>c>>z;
        add_edge(x,y,c,z);
    }
    pair<int,int> rez = maxflow_mincost(src,dest);
    fout<<rez.second;
    return 0;
}