Pagini recente » Rating infoarena | Cod sursa (job #419520) | Cod sursa (job #3278766) | Cod sursa (job #1903779) | Cod sursa (job #294211)
Cod sursa(job #294211)
#include <stdio.h>
#include <vector>
#include <deque>
using namespace std;
#define MAX_N 351
#define inf 0x3f3f3f3f
int N, M, S, D, Sum, Drum, B;
int F[MAX_N][MAX_N], Cap[MAX_N][MAX_N], Cost[MAX_N][MAX_N], Dist[MAX_N], U[MAX_N], H[MAX_N], P[MAX_N], T[MAX_N];
vector <int> A[MAX_N];
deque <int> Q;
long long R;
void BellmanFord()
{
Q.push_back(S);
U[S] = 1;
int i;
for ( i = 1; i <= N; ++i ) Dist[i] = inf;
Dist[S] = 0;
while(Q.empty() == false)
{
int x = Q.front();
int n = A[x].size();
int j;
for ( j = 0; j < n; ++j )
if(Cap[x][A[x][j]]-F[x][A[x][j]] > 0 && Dist[x]+Cost[x][A[x][j]] < Dist[A[x][j]])
{
Dist[A[x][j]] = Dist[x] + Cost[x][A[x][j]];
if(!U[A[x][j]])
{
Q.push_back(A[x][j]);
U[A[x][j]] = 1;
}
}
U[x] = 0;
Q.pop_front();
}
Sum = Dist[D];
}
void Push(int k)
{
while(k > 1)
{
int t = k >> 1;
if(Dist[H[t]] > Dist[H[k]])
{
P[H[t]] = k;
P[H[k]] = t;
H[t] ^= H[k] ^= H[t] ^= H[k];
k = t;
}
else
k = 1;
}
}
void Pop(int r, int b)
{
while(r << 1 <= b)
{
int st = Dist[H[r<<1]];
int dr, x = r << 1;
if((r<<1) + 1 <= b) dr = Dist[H[(r<<1)+1]];
else
dr = st + 1;
if(st > dr) ++ x;
if(Dist[H[x]] < Dist[H[r]])
{
P[H[x]] = r;
P[H[r]] = x;
H[x] ^= H[r] ^= H[x] ^= H[r];
r = x;
}
else
r = b;
}
}
int Min(int i, int j)
{
return
i < j ? i : j;
}
long long Dijkstra()
{
int i, n, j;
for ( i = 1; i <= N; ++i )
{
n = A[i].size();
for ( j = 0; j < n; ++j )
if(Dist[i] != inf && Dist[A[i][j]] != inf) Cost[i][A[i][j]] += Dist[i] - Dist[A[i][j]];
}
for ( i = 1; i <= N; ++i )
{
Dist[i] = inf;
H[i] = i;
P[i] = i;
T[i] = -1;
}
Dist[S] = 0;
H[1] = S; H[S] = 1;
P[S] = 1; P[1] = S;
B = N;
while(B > 1 && Dist[H[1]] != inf)
{
int nd = H[1];
int n = A[nd].size(), j;
for ( j = 0; j < n; ++j )
if(Cap[nd][A[nd][j]]-F[nd][A[nd][j]] > 0 && Dist[nd]+Cost[nd][A[nd][j]] < Dist[A[nd][j]])
{
Dist[A[nd][j]] = Dist[nd] + Cost[nd][A[nd][j]];
T[A[nd][j]] = nd;
Push(P[A[nd][j]]);
}
H[1] = H[B--];
P[H[1]] = 1;
Pop(1, B);
}
if(Dist[D] != inf)
{
Drum = 1;
int r = inf;
for ( i = D; i != S; i = T[i] ) r = Min(r, Cap[T[i]][i]-F[T[i]][i]);
for ( i = D; i != S; i = T[i] )
{
F[T[i]][i] += r;
F[i][T[i]] -= r;
}
Sum += Dist[D];
return Sum * r;
}
return 0;
}
long long Flux()
{
Drum = 1;
while(Drum)
{
Drum = 0;
R += Dijkstra();
}
return R;
}
int main()
{
freopen("fmcm.in", "rt", stdin);
freopen("fmcm.out", "wt", stdout);
scanf("%d %d %d %d", &N, &M, &S, &D);
int i, x, y, cap, z;
for ( i = 1; i <= M; ++i )
{
scanf("%d %d %d %d", &x, &y, &cap, &z);
Cap[x][y] = cap;
Cost[x][y] = z;
Cost[y][x] = -z;
A[x].push_back(y);
A[y].push_back(x);
}
BellmanFord();
printf("%lld\n", Flux());
fclose(stdin);
fclose(stdout);
return 0;
}