Cod sursa(job #2701139)

Utilizator MateGMGozner Mate MateGM Data 29 ianuarie 2021 22:04:32
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.65 kb
#include <fstream>
#include <vector>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;

#define maxn  360

ifstream be("fmcm.in");
ofstream ki("fmcm.out");
int cap[maxn][maxn];
int c[maxn][maxn];
vector<int>adj[maxn];
int new_d[maxn],old_d[maxn],real_d[maxn], d[maxn],l[maxn],in[maxn];

int n,m,fin,start;
int flow,flow_cost;

bool dijkstra()
{
    memset(d,0x3f,sizeof(d));
    d[start]=0;
    real_d[start]=0;
    priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int>> >q;
    q.push({d[start],start});
    while(!q.empty())
    {
        auto best=q.top();
        int du=best.first;
        int u=best.second;

        q.pop();

        if(du!=d[u])continue;

        for(auto p :adj[u])
        {
            if(cap[u][p]){
                int new_d = d[u] + c[u][p] + old_d[u] - old_d[p];
                if (new_d < d[p])
                {
                    d[p] = new_d;
                    real_d[p] = real_d[u] + c[u][p];
                    l[p] = u;
                    //cout<<p<<endl;
                    q.push({d[p], p});
                }
            }
        }
    }
    memcpy(old_d,real_d,sizeof(d));
    if(d[fin]==0x3f3f3f3f)
        return false;
    int minim=0x3f3f3f3f,curcs=0;
    for(int i=fin;i!=start;i=l[i]){
        minim=min(minim,cap[l[i]][i]);
        curcs+=c[l[i]][i];
    }
    flow+=minim;
    flow_cost+=minim*real_d[fin];
    for(int i=fin;i!=start;i=l[i])
    {
        cap[l[i]][i]-=minim;
        cap[i][l[i]]+=minim;
    }
    return true;
}


bool bellmanford()
{
    memset(old_d,0x3f,sizeof(old_d));
    old_d[start]=0;
    queue<int>q;
    //q.push(start);
    vector<bool>in_queue(n+1,false);
    for(q.push(start),in[start]=1;!q.empty();q.pop())
    {
        int i=q.front();
        in_queue[i]=false;
        for(auto p:adj[i])
        {
            if(cap[i][p])
            {
                if(old_d[i]+c[i][p]>=old_d[p])
                    continue;
                old_d[p]=old_d[i]+c[i][p];
                if(in_queue[p])
                    continue;
                in_queue[p]=true;
                q.push(p);

            }
        }
    }
    if(old_d[fin]==0x3f3f3f3f)
        return false;
    return true;

}

int main()
{
    int n,m;
    be>>n>>m>>start>>fin;
    for(int i=1;i<=m;i++)
    {
        int x,y,capa,z;
        be>>x>>y>>capa>>z;
        adj[x].push_back(y);
        adj[y].push_back(x);
        cap[x][y]=capa;
        c[x][y]=z;
        c[y][x]=-z;
    }
    flow=flow_cost=0;
    bellmanford();
    while(dijkstra());
    ki<<flow_cost;

    return 0;
}