Cod sursa(job #2943957)

Utilizator NutaAlexandruASN49K NutaAlexandru Data 21 noiembrie 2022 21:09:15
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.14 kb
#include <fstream>
#include<vector>
#include <algorithm>
#import <cmath>
#import <cassert>
#import <queue>
using namespace std;
class flux
{
    struct duo
    {
        int nod,val;
    };
    vector<vector<int>>f,cap;
    vector<int>t;
    vector<vector<duo>>a;
    int n;
    vector<int>dist;
    bool ford(int s,int d)
    {
        fill(dist.begin(),dist.end(),2e9);
        dist[s]=0;
        queue<duo>q;
        q.push({s,0});
        while(q.size())
        {
            auto acm=q.front();
            q.pop();
            if(acm.val!=dist[acm.nod])continue;
            for(auto &c:a[acm.nod])
            {
                if(cap[acm.nod][c.nod]!=f[acm.nod][c.nod] && dist[acm.nod]+c.val<dist[c.nod])
                {
                    t[c.nod]=acm.nod;
                    dist[c.nod]=dist[acm.nod]+c.val;
                    if(c.nod!=d)
                    {
                        q.push({c.nod,dist[c.nod]});
                    }
                }
            }
        }
        return (dist[d]!=2e9);
    }
public:
    flux(int n)
    {
        this->n=n;
        a=vector<vector<duo>>(n+1);
        f=cap=vector<vector<int>>(n+1,vector<int>(n+1,0));
        t=dist=vector<int>(n+1);
    }
    void add_edge(int x,int y,int cap,int cost)
    {
        this->cap[x][y]=cap;
        a[x].push_back({y,cost});
        a[y].push_back({x,-cost});
    }
    int get_ans(int s,int d)
    {
        int rez=0;
        while(ford(s,d))
        {
            int val=2e9;
            for(int i=d;i!=s;i=t[i])
            {
                val=min(val,cap[t[i]][i]-f[t[i]][i]);
            }
            for(int i=d;i!=s;i=t[i])
            {
                f[t[i]][i]+=val;
                f[i][t[i]]-=val;
            }
            rez+=(val*dist[d]);
        }
        return rez;
    }
};
main()
{
    ifstream cin("fmcm.in");
    ofstream cout("fmcm.out");
    int n,m,s,d;
    cin>>n>>m>>s>>d;
    flux solve(n);
    for(int i=1;i<=m;i++)
    {
        int x,y,cap,cost;
        cin>>x>>y>>cap>>cost;
        solve.add_edge(x,y,cap,cost);
    }
    cout<<solve.get_ans(s,d);

}