Pagini recente » Monitorul de evaluare | Cod sursa (job #2646076) | Cod sursa (job #3291126) | Cod sursa (job #1978066) | Cod sursa (job #279924)
Cod sursa(job #279924)
#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);
}