Cod sursa(job #349096)
#include<stdio.h>
#define INF 13000000
struct Nod {
int V;
int C;
int CS;
Nod *Next;
};
struct NodHeap {
int Val;
};
struct Muchie {
int x;
int y;
int dist;
};
Nod *a[355];
int drum;
int N;
int Ds[355][355];
int Heap[200000];
int Wh[800];
long long Res;
int M;
int C[352][352];
int F[352][352];
int countDij;
int x;
int Dist[400];
int aux;
int Sum;
int y;
int countE;
int extractNod;
int PozInGraf[20000];
int PozInHeap[20000];
Muchie sir[12505];
int dimHeap;
int s,d;
int c;
int z;
void insert(Nod *&now, int nod, int capac, int cost)
{
Nod *op = new Nod;
op -> V = nod;
op -> C = capac;
op -> CS = cost;
op -> Next = now;
now = op;
}
void BellmanFord()
{
for(int i = 1; i <= N; i++)
Dist[i] = INF;
Dist[s] = 0;
for(int i = 1; i <= N - 1; i++)
{
for(int j = 1; j <= countE; j++)
if (Dist[sir[j].y] > Dist[sir[j].x] + sir[j].dist)
Dist[sir[j].y] = Dist[sir[j].x] + sir[j].dist;
}
Sum = Dist[d];
}
void Swap(int i, int j)
{
int aux;
aux = Heap[i];
Heap[i] = Heap[j];
Heap[j] = aux;
aux = PozInGraf[i];
PozInGraf[i] = PozInGraf[j];
PozInGraf[j] = aux;
aux = PozInHeap[PozInGraf[i]];
PozInHeap[PozInGraf[i]] = PozInHeap[PozInGraf[j]];
PozInHeap[PozInGraf[j]] = aux;
}
void HeapDown(int nod)
{
int min = nod;
if (2 * nod <= dimHeap)
if (Heap[2 * nod] < Heap[min]) min = 2 * nod;
if (2 * nod + 1 <= dimHeap)
{
if (Heap[2 * nod] < Heap[min]) min = 2 * nod;
if (Heap[2 * nod + 1] < Heap[min]) min = 2 * nod + 1;
}
if (min != nod)
{
Swap(min,nod);
HeapDown(min);
}
}
void Modifica()
{
for(int i = 1; i <= N; i++)
for(Nod *it = a[i]; it; it = it -> Next)
if (Dist[i] != INF && Dist[it->V] != INF)
{
it -> CS = it -> CS + Dist[i] - Dist[it->V];
Ds[i][it->V] = it->CS;
}
}
int ExtractMin()
{
Swap(1,dimHeap);
dimHeap--;
HeapDown(1);
return PozInGraf[dimHeap + 1];
}
void HeapUp(int x)
{
while (Heap[x] < Heap[x / 2] && x > 1)
{
Swap(x, x/2);
x /= 2;
}
}
void BuildHeap()
{
for(int i = 1; i <= N; i++)
{
Heap[i] = INF;
PozInHeap[i] = i;
PozInGraf[i] = i;
Wh[i] = -1;
}
Heap[1] = 0;
PozInHeap[s] = 1;
PozInHeap[1] = s;
PozInGraf[1] = s;
PozInGraf[s] = 1;
dimHeap = N;
}
int Dijkstra()
{
BuildHeap();
int flow = 0;
Modifica();
while (dimHeap)
{
extractNod = ExtractMin();
Dist[extractNod] = Heap[PozInHeap[extractNod]];
/*if (extractNod == d)
break*/
for(Nod *it = a[extractNod]; it; it = it -> Next)
{
if (C[extractNod][it->V] - F[extractNod][it->V] > 0)
if (Heap[PozInHeap[it->V]] > Heap[PozInHeap[extractNod]] + it -> CS)
{
Heap[PozInHeap[it->V]] = Heap[PozInHeap[extractNod]] + it -> CS;
HeapUp(PozInHeap[it->V]);
Wh[it->V] = extractNod;
}
}
}
int now = d;
int min = INF;
if (Dist[d] != INF)
{
while (now != s)
{
if (min > C[Wh[now]][now] - F[Wh[now]][now])
min = C[Wh[now]][now] - F[Wh[now]][now];
now = Wh[now];
}
now = d;
while (now != s)
{
F[Wh[now]][now] += min;
F[now][Wh[now]] -= min;
now = Wh[now];
}
drum = 1;
Sum += Dist[d];
return Sum * min;
}
else
{
drum = 0;
return 0;
}
}
void Flux()
{
drum = 1;
while(drum)
{
drum = 0;
Res += Dijkstra();
}
}
int main()
{
freopen("fmcm.in","r",stdin);
freopen("fmcm.out","w",stdout);
scanf("%d %d %d %d", &N, &M, &s, &d);
while (M)
{
scanf("%d %d %d %d",&x, &y, &c, &z);
countE++;
C[x][y] = c;
sir[countE].x = x;
sir[countE].y = y;
sir[countE].dist = z;
insert(a[x],y,c,z);
insert(a[y],x,0,-z);
M--;
}
BellmanFord();
// Modifica();
Flux();
printf("%lld",Res);
}