Cod sursa(job #2017760)

Utilizator Laura_CorneiLaura Maria Cornei Laura_Cornei Data 2 septembrie 2017 14:08:19
Problema Flux maxim de cost minim Scor 80
Compilator cpp Status done
Runda Arhiva educationala Marime 4.76 kb
#include <fstream>
#include <string.h>
#include <stdlib.h>
#define nmax 355
#define mmax  12505
#define inf 125050000
using namespace std;
fstream f1("fmcm.in", ios::in);
fstream f2("fmcm.out", ios::out);
int n, m, s, d, ok=1;
int aux[nmax], cap[nmax], cost[nmax][nmax], ca[nmax][nmax], v[mmax*2], viz[nmax], coada[mmax], prim, ultim, k, pred[nmax], poz[nmax];
long int dreal1[nmax],  dreal2[nmax], dfictiv[nmax], fmax, nrelh;
struct muchii
{
    int x, y;
}muc[mmax];
struct heap
{
    int32_t nod, dist;
} h[nmax], vii;
void citire()
{
    int x, y, c, i,CA;
    f1>>n>>m>>s>>d;
    for(i=1; i<=m; i++)
    {
        f1>>muc[i].x>>muc[i].y>>CA>>c;
        aux[muc[i].x]++;
        aux[muc[i].y]++;
        cost[muc[i].x][muc[i].y]=c;
        cost[muc[i].y][muc[i].x]=-c;
        ca[muc[i].x][muc[i].y]=CA;
    }
    cap[1]=1;
    for(i=2; i<=n+1; i++)
    {
        cap[i]=cap[i-1]+aux[i-1];
        aux[i-1]=cap[i-1];
    }
    for(i=1; i<=m; i++)
    {
        x=muc[i].x;
        y=muc[i].y;
        v[aux[x]]=y;
        aux[x]++;
        v[aux[y]]=x;
        aux[y]++;
    }
}
void initb()
{
    for(int i=1; i<=n; i++)
        dreal1[i]=inf;
    prim=1;
    ultim=1;
    k=1;
    coada[prim]=s;
    viz[s]=1;
    dreal1[s]=0;
}
void bellman()
{
    int nod, vec, i;
    while(k!=0)
    {
        nod=coada[prim];
        viz[nod]=0;
        prim++;
        if(prim> mmax-2) prim=1;
        k--;

        for(i=cap[nod]; i<cap[nod+1]; i++)
        {
            vec=v[i];
            if((ca[nod][vec]>0)&&(dreal1[vec]> dreal1[nod]+cost[nod][vec]))
            {
                dreal1[vec]= dreal1[nod]+cost[nod][vec];
                pred[vec]=nod;
                if(!viz[vec])
                {
                    viz[vec]=1;
                    ultim++;
                    if(ultim> mmax-2) ultim=1;
                    k++;
                    coada[ultim]=vec;
                }
            }
        }
    }
    if(dreal1[d]!=inf)  ok=1;
    else ok=0;
}
void actual()
{
  int nod;
  long int fmin=inf;

  nod=d;
  while(pred[nod])
  {
      if(fmin> ca[pred[nod]][nod]) fmin= ca[pred[nod]][nod];
      nod=pred[nod];
  }

  nod=d;
  while(pred[nod])
  {
      ca[pred[nod]][nod]-=fmin;
      ca[nod][pred[nod]]+=fmin;
      nod=pred[nod];
  }

  fmax+=dreal2[d]*fmin;
}
void initd()
{
    int32_t i;
    h[1].nod=s;
    h[1].dist=0;
    poz[s]=1;
    nrelh=1;
    for(i=1; i<=n; i++)
        if(i!=s)
    {
        nrelh++;
        h[nrelh].nod=i;
        poz[i]=nrelh;
        h[nrelh].dist=inf;
    }

}
void elimina_varf()
{
    h[1]=h[nrelh];
    nrelh--;
    vii=h[1];
    int32_t tata=1, fiu=tata*2;
    if((fiu+1<=nrelh)&&(h[fiu+1].dist < h[fiu].dist)) fiu++;

    while((fiu<=nrelh)&&(vii.dist> h[fiu].dist))
    {
        h[tata]=h[fiu];
        poz[h[fiu].nod]=tata;
        tata=fiu;
        fiu*=2;
        if((fiu+1<=nrelh)&&(h[fiu+1].dist < h[fiu].dist)) fiu++;
    }
    h[tata]=vii;
    poz[vii.nod]=tata;
}
void coboara_urca(int32_t indice)
{
    int32_t tata=indice, fiu=indice*2, mos;
    vii=h[indice];
    if((fiu+1<=nrelh)&&(h[fiu+1].dist < h[fiu].dist)) fiu++;

    while((fiu<=nrelh)&&(vii.dist> h[fiu].dist))
    {
        h[tata]=h[fiu];
        ///muti h[fiu] pe pozitia h[tata]
        poz[h[fiu].nod]=tata;
        tata=fiu;
        fiu*=2;
        if((fiu+1<=nrelh)&&(h[fiu+1].dist < h[fiu].dist)) fiu++;
    }
     h[tata]=vii;

     mos=tata/2;
     ////vii memo nodul curent de comparat
     while((mos>=1)&&(h[mos].dist>vii.dist))
     {
         h[tata]=h[mos];
         poz[h[mos].nod]=tata;
         tata=mos;
         mos/=2;
     }
     h[tata]=vii;
     poz[vii.nod]=tata;
}
void dijkstra()
{
    int vfmin, i, j, vec;
    long int mini;
    for(i=1; i<=n; i++)
        dfictiv[i]=inf;
    dreal2[s]=0;
    dfictiv[s]=0;


    for(i=1; i<=n; i++)
    {
        mini=h[1].dist;
        vfmin=h[1].nod;

        for(j=cap[vfmin]; j<cap[vfmin+1]; j++)
            if((poz[v[j]]<=nrelh)&&(ca[vfmin][v[j]]>0))
        {
            vec=v[j];
            if(h[poz[vec]].dist > mini +cost[vfmin][vec]+ dreal1[vfmin]-dreal1[vec])
            {
                pred[vec]=vfmin;
                h[poz[vec]].dist = mini +cost[vfmin][vec]+ dreal1[vfmin]-dreal1[vec];
                coboara_urca(poz[vec]);
                dreal2[vec]=dreal2[vfmin]+cost[vfmin][vec];
            }
        }
         dfictiv[vfmin]=mini;
        elimina_varf();
    }

    memcpy(dreal1, dreal2, sizeof(dreal1));
    if(dfictiv[d]==inf) ok=0;
}
int main()
{
    citire();
    initb();
    bellman();
    while(ok)
    {
        initd();
        dijkstra();
        if(ok) actual();
    }
    f2<<fmax;
    return 0;
}