Pagini recente » Cod sursa (job #1548541) | Cod sursa (job #628818) | Cod sursa (job #2812418) | Cod sursa (job #2440849) | Cod sursa (job #2892249)
#include <bits/stdc++.h>
#define MAX_N 350
#define MULT (1 << 30)
using namespace std;
struct FLOW {
struct elemPQ {
int u, cost;
bool operator < (const elemPQ &a) const {
return cost > a.cost;
}
};
int s, t, vt;
bool inQ[MAX_N], vis[MAX_N];
int cap[MAX_N][MAX_N], cost[MAX_N][MAX_N], flux[MAX_N][MAX_N], parent[MAX_N], realCost[MAX_N], newCost[MAX_N], fakeCost[MAX_N];
vector <int> edges[MAX_N];
void add_edge( int u, int v, int c, int z ) {
edges[u].push_back( v );
edges[v].push_back( u );
cap[u][v] = c;
cost[u][v] = z;
cost[v][u] = -z;
}
void bellman() {
int u;
queue <int> q;
for ( u = 0; u < vt; u++ )
newCost[u] = MULT;
for ( u = 0; u < vt; u++ )
inQ[u] = false;
newCost[s] = 0;
q.push( s );
while ( !q.empty() ) {
u = q.front();
q.pop();
inQ[u] = false;
for ( int v: edges[u] ) {
if ( newCost[u] + cost[u][v] < newCost[v] && flux[u][v] < cap[u][v] ) {
parent[v] = u;
newCost[v] = newCost[u] + cost[u][v];
if ( !inQ[v] ) {
q.push( v );
inQ[v] = true;
}
}
}
}
}
bool dijkstra() {
int u;
priority_queue <elemPQ> pq;
for ( u = 0; u < vt; u++ ) {
parent[u] = -1;
realCost[u] = newCost[u];
fakeCost[u] = MULT;
vis[u] = false;
}
newCost[s] = fakeCost[s] = 0;
pq.push( { s, 0 } );
while ( !pq.empty() ) {
u = pq.top().u;
pq.pop();
if ( !vis[u] ) {
vis[u] = true;
for ( int v: edges[u] ) {
if ( fakeCost[u] + cost[u][v] + realCost[u] - realCost[v] < fakeCost[v] && flux[u][v] < cap[u][v] ) {
parent[v] = u;
fakeCost[v] = fakeCost[u] + cost[u][v] + realCost[u] - realCost[v];
newCost[v] = newCost[u] + cost[u][v];
pq.push( { v, fakeCost[v] } );
}
}
}
}
return fakeCost[t] != MULT;
}
int minCostmaxFlow() {
int maxFlow, newFlow, minCost, newCost, v;
bellman();
maxFlow = 0;
minCost = 0;
while ( dijkstra() ) {
newFlow = MULT;
newCost = 0;
v = t;
while ( v != s ) {
newFlow = min( newFlow, cap[parent[v]][v] - flux[parent[v]][v] );
newCost += cost[parent[v]][v];
v = parent[v];
}
maxFlow += newFlow;
minCost += newFlow * newCost;
v = t;
while ( v != s ) {
flux[parent[v]][v] += newFlow;
flux[v][parent[v]] -= newFlow;
v = parent[v];
}
}
return minCost;
}
};
FLOW flow;
int main() {
ifstream cin( "fmcm.in" );
ofstream cout( "fmcm.out" );
int n, m, s, t, u, v, c, z, i;
cin >> n >> m >> s >> t;
s--;
t--;
for ( i = 0; i < m; i++ ) {
cin >> u >> v >> c >> z;
u--;
v--;
flow.add_edge( u, v, c, z );
}
flow.s = s;
flow.t = t;
flow.vt = n;
cout << flow.minCostmaxFlow();
return 0;
}