Cod sursa(job #2466821)

Utilizator MortemPlaiasu Iulia-Silvia Mortem Data 2 octombrie 2019 23:16:33
Problema Flux maxim de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.26 kb
#include <iostream>
#include <fstream>
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include <algorithm>
#include <vector>
#include <queue>

#define NMX 400
#define FORI(i) for(vector<int>::iterator it= v[i].begin();it!=v[i].end();++it)
using namespace std;

int n,m,s,t;
vector<int> v[NMX];
int F[NMX][NMX];
int C[NMX][NMX];
int Ct[NMX][NMX];
int CtV[NMX];
int rCtV[NMX];
bool vis[NMX];
int p[NMX];
int dist[NMX];
bool inQ[NMX];
struct elem
{
  int i,c;
};

struct Comp: binary_function<elem,elem,bool>
{
  bool operator() (elem e1, elem e2)
  {
    return e1.c>e2.c;
  }
};

long c;
int main()
{
  freopen("fmcm.in","r",stdin);
  freopen("fmcm.out","w",stdout);

  scanf("%d %d %d %d",&n,&m,&s,&t);
  for(int i=0;i<m;i++)
  {
    int j,k,f,c;
    scanf("%d %d %d %d",&j,&k,&f,&c);
    v[j].push_back(k);
    v[k].push_back(j);
    C[j][k]=f;
    Ct[j][k]=c;
    Ct[k][j]=-c;
  }
  queue<int> q= queue<int>();
  for(int i=1;i<=n;i++)
    dist[i]=20000;
  q.push(s);
  dist[s]=0;
  CtV[s]=0;
  inQ[s]=1;
  while(!q.empty())
  {
    int tp =q.front();
    FORI(tp)
      if(dist[*it]>dist[tp]+Ct[tp][*it]&&
        C[tp][*it]>F[tp][*it])
      {
        dist[*it]=dist[tp]+Ct[tp][*it];
        if(!inQ[*it])
        {
          q.push(*it);
          inQ[*it]=1;
        }
      }
    inQ[tp]=0;
    q.pop();
  }
  while(1)
  {
    priority_queue<elem,vector<elem>,Comp > pq= priority_queue<elem,vector<elem>,Comp >();
    pq.push({s,0});
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)CtV[i]=20000;
    CtV[s]=0;
    while(!pq.empty())
    {
      elem tp = pq.top();
      pq.pop();
      if(vis[tp.i]) continue;
      FORI(tp.i)
      {
        if(CtV[*it]>tp.c+Ct[tp.i][*it]+dist[tp.i]-dist[*it] &&
        C[tp.i][*it]>F[tp.i][*it])
        {
          p[*it]=tp.i;
          rCtV[*it]=rCtV[tp.i]+Ct[tp.i][*it];
          CtV[*it]=tp.c+Ct[tp.i][*it]+dist[tp.i]-dist[*it];
          pq.push({*it,CtV[*it]});
        }
      }
      vis[tp.i]=1;
    }
    memcpy(dist,rCtV,sizeof(dist));
    if(!vis[t]) break;
    int minn = INT_MAX;
    for(int nod=t;nod!=s;nod=p[nod])
      minn=min(minn,C[p[nod]][nod]-F[p[nod]][nod]);
    for(int nod=t;nod!=s;nod=p[nod])
    {
      c+=((long)Ct[p[nod]][nod])*minn;
      F[p[nod]][nod]+=minn;
      F[nod][p[nod]]-=minn;
    }
  }
  printf("%ld",c);
}