Cod sursa(job #2591227)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 30 martie 2020 00:59:04
Problema Flux maxim de cost minim Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.15 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
#include <bitset>
 
#define INF 0x3f3f3f3f
 
#define Nmax 370
#define v first
#define e second
 
using namespace std;
 
class edge{
public:
    int x,y,cost,capacity,flow;
    edge(){
        x = y = cost = capacity = flow = 0;
    }
    edge(int a,int b,int cs,int cap,int fl){
        x = a;
        y = b;
        cost = cs;
        capacity = cap;
        flow = fl;
    }
};
vector<edge> E;
vector<pair<int,int> > G[Nmax];
bitset<Nmax> inQ;
queue<int> Q;
priority_queue<pair<int,int> > H;
int nre = -1,S,D,N,M;
int dist[Nmax],real_dist[Nmax],old_dist[Nmax],daddy[Nmax];
 
void Insert(int a,int b,int cs,int cap,int fl){
    ++nre;
    E.push_back(edge(a,b,cs,cap,fl));
    G[a].push_back(make_pair(b,nre));
}
 
void Read()
{
    scanf("%d%d%d%d",&N,&M,&S,&D);
    int a,b,c,d;
    for(int i = 1; i <= M; ++i){
        scanf("%d%d%d%d",&a,&b,&c,&d);
        Insert(a,b,d,c,0);
        Insert(b,a,-d,0,0);
    }
}
 
void Bellman_ford(int k)
{
    memset(old_dist,INF,sizeof(old_dist));
    old_dist[k] = 0;
    Q.push(k);
    while(!Q.empty())
    {
        k = Q.front(); Q.pop();
        inQ[k] = 0;
        for(vector<pair<int,int> >::iterator it = G[k].begin(); it != G[k].end(); ++it)
            if(old_dist[it->v] > old_dist[k] + E[it->e].cost&&
               E[it->e].flow != E[it->e].capacity)
            {
                old_dist[it->v] = old_dist[k] + E[it->e].cost;
                if(inQ[it->v])
                    continue;
                inQ[it->v] = 1;
                Q.push(it->v);
            }
    }
}
 
bool Dijkstra(int k)
{
    int cs;
    memset(dist,INF,sizeof(dist));
    memset(real_dist,INF,sizeof(real_dist));
    dist[k] = 0;
    real_dist[k] = 0;
    H.push(make_pair(0,k));
    while(!H.empty())
    {
        k = H.top().second;cs = -H.top().first;H.pop();
        if(k == D) continue;
        if(cs != dist[k]) continue;
        for(vector<pair<int,int> >::iterator it = G[k].begin(); it != G[k].end(); ++it)
            if(dist[it->v] > dist[k] + E[it->e].cost + old_dist[k] - old_dist[it->v]
               && E[it->e].capacity != E[it->e].flow)
            {
                dist[it->v] = dist[k] + E[it->e].cost + old_dist[k] - old_dist[it->v];
                real_dist[it->v] = real_dist[k] + E[it->e].cost;
                daddy[it->v] = it->e;
                H.push(make_pair(-dist[it->v],it->v));
            }
    }
    memcpy(old_dist,real_dist,sizeof(real_dist));
    return dist[D] < INF;
}
 
void FLOW(int k)
{
    int minFLOW,maxFLOW = 0,minCOST = 0;
    Bellman_ford(k);
    while(Dijkstra(k))
    {
        minFLOW = INF;
        for(int nodc = D; nodc != S; nodc = E[daddy[nodc]].x)
            minFLOW = min(minFLOW,E[daddy[nodc]].capacity - E[daddy[nodc]].flow);
        for(int nodc = D; nodc != S; nodc = E[daddy[nodc]].x)
        {
            E[daddy[nodc]].flow += minFLOW;
            E[daddy[nodc]^1].flow -= minFLOW;
        }
        maxFLOW += minFLOW;
        minCOST += minFLOW * real_dist[D];
    }
    printf("%d\n",minCOST);
}
 
int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
 
    Read();
    FLOW(S);
 
    return 0;
}