Pagini recente » Cod sursa (job #293549) | Cod sursa (job #1759536) | Cod sursa (job #3204767) | Cod sursa (job #299982) | Cod sursa (job #1585285)
#include <bits/stdc++.h>
using namespace std;
const int MAX_N = 350;
const int MAX_M = 12500;
const int NIL = -1;
const int INF = numeric_limits <int> :: max() / 2;
struct Edge
{
int v;
int cap, cost;
int next;
};
Edge G[2 * MAX_M];
int head[MAX_N];
int D[MAX_N];
bool inQueue[MAX_N];
int Q[MAX_N];
int qStart, qEnd;
int N;
int source, sink;
void addEdge(int u, int v, int cap, int cost, int pos)
{
G[pos] = { v, cap, cost, head[u] };
head[u] = pos;
}
void SPFA()
{
Q[0] = source;
qStart = 0; qEnd = 1;
for ( int i = 0; i < N; i++ )
D[i] = INF;
D[source] = 0;
while ( qStart != qEnd )
{
int u = Q[qStart++];
inQueue[u] = 0;
for ( int i = head[u]; i != NIL; i = G[i].next )
{
int v = G[i].v;
if ( G[i].cap > 0 && D[u] + G[i].cost < D[v] )
{
D[v] = D[u] + G[i].cost;
if ( !inQueue[v] )
{
inQueue[v] = 1;
Q[qEnd++] = v;
}
}
}
}
for ( int i = 0; i < N; i++ )
D[i] = D[sink] - D[i];
}
int augment(int u, int flow)
{
if ( u == sink )
return flow;
inQueue[u] = 1;
int ret = flow;
for ( int i = head[u]; i != NIL; i = G[i].next )
{
int v = G[i].v;
if ( G[i].cap && !inQueue[v] && D[v] + G[i].cost == D[u] )
{
int newFlow = augment( v, min( G[i].cap, ret ) );
G[i].cap -= newFlow;
G[i ^ 1].cap += newFlow;
ret -= newFlow;
if ( !ret )
return flow;
}
}
return flow - ret;
}
bool adjust()
{
int delta = INF;
for ( int u = 0; u < N; u++ )
{
if ( inQueue[u] )
{
for ( int i = head[u]; i != NIL; i = G[i].next )
{
int v = G[i].v;
if ( G[i].cap > 0 && !inQueue[v] )
delta = min( delta, D[v] + G[i].cost - D[u] );
}
}
}
if ( delta == INF )
return 0;
for ( int i = 0; i < N; i++ )
if ( inQueue[i] )
D[i] += delta;
for ( int i = 0; i < N; i++ )
inQueue[i] = 0;
return 1;
}
int main()
{
ifstream in("fmcm.in");
in.tie(0);
ios_base::sync_with_stdio(false);
int M;
in >> N >> M >> source >> sink;
source--; sink--;
for ( int i = 0; i < N; i++ )
head[i] = NIL;
for ( int i = 0; i < M; i++ )
{
int u, v, cost, cap;
in >> u >> v >> cap >> cost;
addEdge( u - 1, v - 1, cap, cost, 2 * i );
addEdge( v - 1, u - 1, 0, -cost, 2 * i + 1 );
}
int tmp, flow = 0;
SPFA();
do
{
tmp = 0;
do
{
for ( int i = 0; i < N; i++ )
inQueue[i] = 0;
tmp = augment( source, INF );
flow += tmp;
} while ( tmp );
} while ( adjust() );
int cost = 0;
for ( int i = 0; i < M; i++ )
cost += G[2 * i + 1].cap * G[2 * i].cost;
ofstream out("fmcm.out");
out << cost << '\n';
out.close();
return 0;
}