Pagini recente » Cod sursa (job #1815347) | Cod sursa (job #1501909) | Cod sursa (job #242280) | Cod sursa (job #2691874) | Cod sursa (job #2764112)
/**
____ ____ ____ ____ ____
||a |||t |||o |||d |||o ||
||__|||__|||__|||__|||__||
|/__\|/__\|/__\|/__\|/__\|
**/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N_MAX = 350;
int n, m;
int source, sink;
int cap[N_MAX + 2][N_MAX + 2];
int flow[N_MAX + 2][N_MAX + 2];
int cost[N_MAX + 2][N_MAX + 2];
vector <int> adj[N_MAX + 2];
void addEdge (int u, int v, int ecap, int ecost)
{
adj[u].push_back(v);
adj[v].push_back(u);
cap[u][v] = ecap;
cap[v][u] = 0;
flow[u][v] = 0;
flow[v][u] = 0;
cost[u][v] = ecost;
cost[v][u] = -ecost;
}
int prec[N_MAX + 2];
void BellmanFord ()
{
for(int u = 1; u <= n; u++)
prec[u] = INT_MAX;
queue <int> q;
prec[source] = 0;
q.push(source);
while(q.empty() == false)
{
int u = q.front();
q.pop();
for(int v : adj[u])
if(cap[u][v] > 0)
{
if(prec[u] + cost[u][v] < prec[v])
{
prec[v] = prec[u] + cost[u][v];
q.push(v);
}
}
}
}
int dist[N_MAX + 2];
int newPrec[N_MAX + 2];
int parent[N_MAX + 2];
bool visited[N_MAX + 2];
bool Dijkstra ()
{
for(int u = 1; u <= n; u++)
{
parent[u] = -1;
dist[u] = INT_MAX;
visited[u] = false;
}
priority_queue <pair <int, int>> q;
dist[source] = 0;
newPrec[source] = 0;
parent[source] = 0;
q.push(make_pair(-dist[source], source));
while(q.empty() == false)
{
int u = q.top().second;
q.pop();
if(visited[u] == true)
continue;
visited[u] = true;
for(int v : adj[u])
if(flow[u][v] < cap[u][v])
{
if(dist[u] + ((prec[u] - prec[v]) + cost[u][v]) < dist[v])
{
dist[v] = dist[u] + ((prec[u] - prec[v]) + cost[u][v]);
newPrec[v] = newPrec[u] + cost[u][v];
parent[v] = u;
q.push(make_pair(-dist[v], v));
}
}
}
for(int u = 1; u <= n; u++)
prec[u] = newPrec[u];
return parent[sink] != -1;
}
int minCost ()
{
int answer = 0;
while(Dijkstra() == true)
{
int push = INT_MAX;
int sumCost = 0;
{
int u = sink;
while(u != source)
{
int v = parent[u];
push = min(push, cap[v][u] - flow[v][u]);
sumCost += cost[v][u];
u = v;
}
}
{
int u = sink;
while(u != source)
{
int v = parent[u];
flow[v][u] += push;
flow[u][v] -= push;
u = v;
}
}
answer += sumCost * push;
}
return answer;
}
int main()
{
ifstream fin ("fmcm.in");
ofstream fout ("fmcm.out");
fin >> n >> m >> source >> sink;
for(int it = 1; it <= m; it++)
{
int u, v, ecap, ecost;
fin >> u >> v >> ecap >> ecost;
addEdge(u, v, ecap, ecost);
}
BellmanFord();
fout << minCost() << "\n";
return 0;
}