Pagini recente » Cod sursa (job #266743) | Cod sursa (job #3280976) | Monitorul de evaluare | Cod sursa (job #12917) | Cod sursa (job #243584)
Cod sursa(job #243584)
#include <cstdio>
#include <vector>
using namespace std;
#define MAX_N 355
#define INF 0x3f3f3f
#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)
vector <int> G[MAX_N];
int N, M, S, D;
int Cap[MAX_N][MAX_N], Cost[MAX_N][MAX_N], F[MAX_N][MAX_N];
int Dist[MAX_N], H[MAX_N], From[MAX_N], P[MAX_N];
int Sum, L;
bool Drum = 1;
void push(int x)
{
int aux;
while (x/2>1 && Dist[H[x]]<Dist[H[x/2]])
{
aux = H[x], H[x] = H[x/2], H[x/2] = aux;
P[H[x]] = x;
P[H[x/2]] = x/2;
x /= 2;
}
}
void pop(int x)
{
int y = 0, aux;
while (x != y)
{
y = x;
if (y*2<=L && Dist[H[x]]>Dist[H[y*2]]) x = y*2;
if (y*2+1 <= L && Dist[H[x]]>Dist[H[y*2+1]]) x = y*2+1;
aux = H[x], H[x] = H[y], H[y] = aux;
P[H[x]] = x;
P[H[y]] = y;
}
}
void BelmanFord()
{
bool ok = 0;
for(int i = 1; i <= N; ++i)
Dist[i] = INF;
Dist[S] = 0;
for(int i = 1; i <= N && !ok; ++i)
{
ok = 1;
for(int j = 1; j <= N; ++j)
foreach(G[j])
if(Cap[j][*it] - F[j][*it] > 0 && Dist[j] + Cost[j][*it] < Dist[*it])
{
ok = 0;
Dist[*it] = Dist[j] + Cost[j][*it];
}
}
Sum = Dist[D];
}
void citire()
{
scanf("%d %d %d %d",&N, &M, &S, &D);
for(int i = 1; i <= M; ++i)
{
int x, y, cap, cost;
scanf("%d %d %d %d",&x, &y, &cap, &cost);
G[x].push_back(y);
G[y].push_back(x);
Cap[x][y] = cap;
Cost[x][y] = cost;
Cost[y][x] = -cost;
}
}
long long Dijkstra()
{
for(int i = 1; i <= N; ++i)
foreach(G[i])
if(Dist[i] != INF && Dist[*it] != INF)
Cost[i][*it] += (Dist[i] - Dist[*it]);
for(int i = 1; i <= N; ++i)
{
Dist[i] = INF;
H[i] = i;
P[i] = i;
From[i] = -1;
}
Dist[S] = 0;
H[1] = S, H[S] = 1;
P[1] = S, P[S] = 1;
L = N;
while(L > 1 && Dist[H[1]] != INF)
{
foreach(G[H[1]])
{
int v = *it;
if(Cap[H[1]][v] - F[H[1]][v] > 0 && Dist[H[1]] + Cost[H[1]][v] < Dist[v])
{
Dist[v] = Dist[H[1]] + Cost[H[1]][v];
From[v] = H[1];
push(P[v]);
}
}
H[1] = H[L--];
P[H[1]] = 1;
if(L > 1) pop(1);
}
if(Dist[D] != INF)
{
int V = INF;
Drum = 1;
for(int i = D; i != S; i = From[i])
V = min(V, Cap[From[i]][i] - F[From[i]][i]);
for(int i = D; i != S; i = From[i])
{
F[From[i]][i] += V;
F[i][From[i]] -= V;
}
Sum += Dist[D];
return V * Sum;
}
return 0;
}
int main()
{
freopen("fmcm.in","rt",stdin);
freopen("fmcm.out","wt",stdout);
citire();
BelmanFord();
long long Rez = 0;
while(Drum)
{
Drum = 0;
Rez += Dijkstra();
}
printf("%lld\n",Rez);
}