Pagini recente » Cod sursa (job #1115814) | Cod sursa (job #2149061) | Cod sursa (job #1040844) | Cod sursa (job #2169253) | Cod sursa (job #2030528)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");
typedef pair<int,int> Pair;
const int Nmax = 355, inf = 1e9;
int n, m, S, D, x, y, cap, cost;
class floow
{
int cost[Nmax][Nmax], cap[Nmax][Nmax], f[Nmax][Nmax], p[Nmax], dist[Nmax], t[Nmax], new_p[Nmax];
vector<int> v[Nmax];
bool InQueue[Nmax];
priority_queue< Pair, vector< Pair >, greater< Pair > > heap;
bool dijkstra()
{
for(int i=1; i<=n; ++i) dist[i] = inf, t[i] = 0;
dist[S] = 0;
heap.push({dist[S], S});
while(heap.size())
{
int node = heap.top().second, nr = heap.top().first;
heap.pop();
if(dist[node] != nr) continue;
for(auto it : v[node])
if(f[node][it] < cap[node][it])
{
int cc = dist[node] + cost[node][it] + p[node] - p[it];
if(dist[it] > cc)
{
t[it] = node;
dist[it] = cc;
heap.push({cc, it});
new_p[it] = new_p[node] + cost[node][it];
}
}
}
for(int i=1; i<=n; ++i) p[i] = new_p[i];
return dist[D] != inf;
}
public:
void prepare()
{
queue<int> q;
q.push(S); p[S] = 0;
while(q.size())
{
int node = q.front();
q.pop();
InQueue[node] = 0;
for(auto it : v[node])
if(f[node][it] < cap[node][it] && p[it] > p[node] + cost[node][it])
{
p[it] = p[node] + cost[node][it];
if(InQueue[it]) continue;
InQueue[it] = 1;
q.push(it);
}
}
}
int max_flow_min_cost()
{
int node, fmin, dad, cc, ans = 0;
while(dijkstra())
{
node = D;
fmin = inf;
while(node != S)
{
dad = t[node];
fmin = min(fmin, cap[dad][node] - f[dad][node]);
node = dad;
}
ans += fmin * p[D];
node = D;
while(node != S)
{
dad = t[node];
f[dad][node] += fmin;
f[node][dad] -= fmin;
node = dad;
}
}
return ans;
}
void add_edge(int x, int y, int Cap, int Cost)
{
v[x].push_back(y);
v[y].push_back(x);
cap[x][y] = Cap, cap[y][x] = 0;
cost[x][y] = Cost, cost[y][x] = -Cost;
f[x][y] = f[y][x] = 0;
}
} graph;
int main()
{
fin >> n >> m >> S >> D;
for(int i=1; i<=m; ++i)
{
fin >> x >> y >> cap >> cost;
graph.add_edge(x, y, cap, cost);
}
graph.prepare();
fout << graph.max_flow_min_cost() << '\n';
return 0;
}