Cod sursa(job #279924)

Utilizator marcelcodreaCodrea Marcel marcelcodrea Data 13 martie 2009 09:09:16
Problema Flux maxim de cost minim Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 4.74 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);   
}