Cod sursa(job #247838)

Utilizator marcelcodreaCodrea Marcel marcelcodrea Data 24 ianuarie 2009 10:44:06
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 4.18 kb
#include<stdio.h>
#define MAX 500000
#define Maxdist 25000000
struct Nod {
    int v;
    Nod *next;
};
struct NHeap {
    int val;
    int nod;
};
int n;
int nrHeap;
int m;
int fSs;
int ok;
int fDt;
int C[355][355];
int UZ;
int x;
int min;
NHeap Heap[800];
int PozInHeap[355];
int y;
int Parent[355];
int q1;
int q2;
int dist[355];
Nod *a[355];
long long val;
int P[355][355];
void insert(Nod *&k, int val)
{
    Nod *u = new Nod;
    u -> v = val;
    u -> next = k;
    k = u;
}
int GoDown(int i)
{
    int min = 2 * i;
    NHeap aux;
    int aux2;
    if (2 * i > nrHeap) return 0;
    if (2 * i + 1 <= nrHeap)
    if (Heap[2 * i].val < Heap[2 * i + 1].val) min = 2 * i;
                                  else min = 2 * i + 1;
    if (Heap[min].val >= Heap[i].val) min = i;
    if (min == i) return 0;
    aux2 = PozInHeap[Heap[min].nod];
    PozInHeap[Heap[min].nod] = PozInHeap[Heap[i].nod];
    PozInHeap[Heap[i].nod] = aux2;

    aux = Heap[min];
    Heap[min] = Heap[i];
    Heap[i] = aux;
    GoDown(min);
    return 0;
}
int GoUp(int i)
{
    while (Heap[i].val < Heap[i / 2].val && i > 1)
     {

         int aux2;
         aux2 = PozInHeap[Heap[i].nod];
         PozInHeap[Heap[i].nod] = PozInHeap[Heap[i/2].nod];
         PozInHeap[Heap[i/2].nod] = aux2;

         NHeap aux;
         aux = Heap[i];
         Heap[i] = Heap[i / 2];
         Heap[i / 2] = aux;

         i /= 2;
     }

}
NHeap ExtractMin()
{
    NHeap aux;
    PozInHeap[Heap[1].nod] = nrHeap;
    PozInHeap[Heap[nrHeap].nod] = 1;
    aux = Heap[1];
    Heap[1] = Heap[nrHeap];
    Heap[nrHeap] = aux;
    nrHeap--;
    GoDown(1);
    return Heap[nrHeap + 1];
}
int BellmanFord()
{
    Nod *j;
    for(int i = 1; i <= n; i++)
     if (i != fSs) dist[i] = MAX;
   for(int k = 1; k <= n - 1; k++)
    for(int i = 1; i <= n; i++)
     for(j = a[i]; j != NULL; j = j -> next)
      if (C[i][j->v])
      if (dist[j -> v] > dist[i] + P[i][j -> v])
       dist[j -> v] = dist[i] + P[i][j -> v];

    for(int i = 1; i <= n; i++)
    {
      Heap[i].val = dist[i];
      Heap[i].nod = i;
      PozInHeap[i] = i;
    }


    UZ = dist[fDt];

    return 0;
}
long long Dijkstra()
{
    nrHeap = 1;

    for(int i = 1; i <= n; i++)
     for(Nod *j = a[i]; j != NULL; j = j -> next)
      if (Heap[PozInHeap[i]].val != Maxdist && Heap[PozInHeap[j -> v]].val != Maxdist)
       P[i][j -> v] += Heap[PozInHeap[i]].val - Heap[PozInHeap[j -> v]].val;

    for(int i = 1; i <= n; i++)
     if (i != fSs)
     {
      Heap[++nrHeap].val = Maxdist;
      PozInHeap[i] = nrHeap;
      Heap[nrHeap].nod = i;
     }
    Heap[1].nod = fSs;
    Heap[1].val = 0;
    PozInHeap[fSs] = 1;
    for(int i = 1; i <= n; i++)
     Parent[i] = 0;
    nrHeap = n;


    while (nrHeap)
      {
          NHeap aux;
          aux = ExtractMin();
          if (aux.nod == fDt) break;
          for(Nod *it = a[aux.nod]; it; it = it -> next)
           if (Heap[PozInHeap[it->v]].val > aux.val + P[aux. nod][it -> v] && C[aux.nod][it -> v] > 0)
            {
             Heap[PozInHeap[it->v]].val = aux.val + P[aux.nod][it -> v];
             Parent[it->v] = aux.nod;
             GoUp(PozInHeap[it->v]);
            }
      }
    if (Parent[fDt] != 0)
    {
     ok = 1;
     min = C[Parent[fDt]][fDt];
     for(int i = Parent[fDt]; i != fSs; i = Parent[i])
      if (min > C[Parent[i]][i]) min = C[Parent[i]][i];

     for(int i = fDt; i != fSs; i = Parent[i])
     {
       C[Parent[i]][i] -= min;
       C[i][Parent[i]] += min;
     }
     UZ += Heap[PozInHeap[fDt]].val;
     return min * UZ;
    }
    return 0;


}
int Flux()
{
    ok = 1;
    while (ok)
     {
         ok = 0;
         val += Dijkstra();
     }

    return 0;
}
int main()
{
    freopen("fmcm.in","r",stdin);
    freopen("fmcm.out","w",stdout);
    scanf("%d %d %d %d", &n, &m, &fSs, & fDt);
    for(int i = 1; i <= m; i++)
     {
       scanf("%d %d %d %d", &x, &y, &q1, &q2);
       P[x][y] = q2;
       P[y][x] = -q2;
       C[x][y] = q1;
       insert(a[x],y);
       insert(a[y],x);
     }
     BellmanFord();
     Flux();
     printf("%lld\n",val);
}