Cod sursa(job #2960375)

Utilizator PHOSSESSEDProsie Radu-Teodor PHOSSESSED Data 4 ianuarie 2023 11:23:19
Problema Flux maxim de cost minim Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.36 kb
#include<fstream>
#include<vector>
#include<queue>
#include<bitset>
#include<cstring>
using namespace std;

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


const int NMAX = 351;
const int INF = 1e9;

int cap[NMAX][NMAX],flow[NMAX][NMAX],cost[NMAX][NMAX];



vector<int> vecini[NMAX];

int t[NMAX],n;

bitset<NMAX> inq;

int bf(int s,int d)
{
    vector<int> dp(NMAX,INF);
    dp[s] = 0; queue<int> q;
    q.push(s);

    inq.reset(); inq[s] = 1;
    memset(t,0,sizeof(t));

    while(!q.empty())
        {
            int v = q.front(); q.pop();
            inq[v] = 0;
            for(auto it : vecini[v])
                {
                    if(!(cap[v][it] - flow[v][it]))///daca nu am capacitate reziduala,nu pot folosi muchia
                        continue;

                    if(dp[v] + cost[v][it] < dp[it])
                        {
                            t[it] = v;
                            dp[it] = dp[v] + cost[v][it];
                            if(!inq[it])
                                {
                                    q.push(it);
                                    inq[it] = 1;
                                }
                        }
                }
        }


    if(dp[d] == INF)///daca nu ajung la destintatie inseamna ca nu exista drum de augmentare
        return 0;

    int r = INF;
    while(d != s)
        {
            r = min(r,cap[t[d]][d] - flow[t[d]][d]);
            d = t[d];
        }

    return r;
}

void wannabe(int s,int d)
{
    ///vreau un drum de cost minim folosind doar muchii de augmentare

    int primesc = bf(s,d);
    long long ans = 0;

    while(primesc > 0)
        {
            int nod = d;
            while(nod != s)
                {
                    flow[t[nod]][nod] += primesc;
                    flow[nod][t[nod]] -= primesc;
                    ans += 1LL * primesc * cost[t[nod]][nod];
                    nod = t[nod];
                }

            primesc = bf(s,d);
        }

    fout << ans;
    exit(0);
}


int main()
{
    int a,b,s,d,c,m,z; fin >> n >> m >> s >> d;
    for(int i = 1; i <= m ; i++)
        {
            fin >> a >> b >> c >> z;
            vecini[a].emplace_back(b);
            cap[a][b] = c;
            cost[a][b] = z;
            cost[b][a] = -z;
        }

    wannabe(s,d);
}