Pagini recente » Cod sursa (job #3216963) | Cod sursa (job #2562684) | Cod sursa (job #2793085) | Cod sursa (job #412077) | Cod sursa (job #3225091)
#ifndef LOCAL
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
#endif
#ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
#define pb push_back
#define pii pair<int, int>
using ll = long long;
using ci = const int;
using cll = const long long;
using namespace std;
const int INF = 1e9 + 7;
/*******************************/
// INPUT / OUTPUT
#ifndef LOCAL
ifstream in("fmcm.in");
ofstream out("fmcm.out");
#define cin in
#define cout out
#endif
/*******************************/
/// GLOBAL DECLARATIONS
int N, M, S, D;
struct Muchie
{
int from, to, cap, cost;
};
struct Graf
{
int n;
vector <int> dist, pre;
vector <vector <int>> adj;
vector <Muchie> muchii;
Graf(int _n)
{
n = _n;
dist.resize(n);
pre.resize(n);
adj.resize(n);
}
inline void adauga_muchie(int from, int to, int cap, int cost)
{
adj[from].push_back(muchii.size());
muchii.push_back({from, to, cap, cost});
adj[to].push_back(muchii.size());
muchii.push_back({to, from, 0, -cost});
}
inline bool bellman_ford(int sursa, int dest)
{
vector <bool> in_queue(n, false);
for (int i = 0 ; i < n ; ++ i) dist[i] = INF;
dist[sursa] = 0; in_queue[sursa] = true;
queue <int> q; q.push(sursa);
int node;
Muchie u;
while (!q.empty())
{
node = q.front();
in_queue[node] = false;
q.pop();
for (auto i: adj[node])
{
u = muchii[i];
if (u.cap && dist[u.to] > dist[node] + u.cost)
{
dist[u.to] = dist[node] + u.cost;
if (!in_queue[u.to])
{
in_queue[u.to] = true;
q.push(u.to);
}
}
}
}
return dist[dest] != INF;
}
inline bool dijkstra(int sursa, int dest)
{
vector <bool> vis(n, false);
vector <int> dist_reala(n), dist_falsa(n, INF);
for (int i = 0 ; i < n ; ++ i)
{
dist_reala[i] = dist[i];
pre[i] = -1;
}
priority_queue <pii> pq; pq.push({0, sursa});
dist_falsa[sursa] = dist[sursa] = 0;
int node;
while (!pq.empty())
{
node = pq.top().second;
pq.pop();
Muchie u;
if (!vis[node])
{
vis[node] = true;
for (auto i: adj[node])
{
u = muchii[i];
if (u.cap && !vis[u.to] && dist_falsa[u.to] > dist_falsa[node] + u.cost + dist_reala[node] - dist_reala[u.to])
{
pre[u.to] = i;
dist_falsa[u.to] = dist_falsa[node] + u.cost + dist_reala[node] - dist_reala[u.to];
dist[u.to] = dist[node] + u.cost;
pq.push({-dist_falsa[u.to], u.to});
}
}
}
}
return dist_falsa[dest] != INF;
}
inline pii push_flux(int sursa, int dest)
{
int flux = INF, cost = 0;
for (int node = dest; node != sursa; node = muchii[pre[node]].from)
{
flux = min(flux, muchii[pre[node]].cap);
cost += muchii[pre[node]].cost;
}
for (int node = dest ; node != sursa ; node = muchii[pre[node]].from)
{
muchii[pre[node]].cap -= flux;
muchii[pre[node] ^ 1].cap += flux;
}
return {flux, flux * cost};
}
inline pii afla_flux(int sursa, int dest)
{
bool ok = bellman_ford(sursa, dest);
if (!ok) return {0, 0};
int cicluri = 0;
pii sol = {0, 0}, ret;
while (dijkstra(sursa, dest))
{
++ cicluri;
ret = push_flux(sursa, dest);
sol.first += ret.first; sol.second += ret.second;
}
return sol;
}
};
/*******************************/
/// FUNCTIONS
void ReadInput();
void Solution();
void Output();
/*******************************/
///-------------------------------------
inline void ReadInput()
{
cin >> N >> M >> S >> D;
S --; D --;
}
///-------------------------------------
inline void Solution()
{
Graf graf = Graf(N);
int a, b, cap, cost;
for (int i = 0 ; i < M ; ++ i)
{
cin >> a >> b >> cap >> cost;
a --; b --;
graf.adauga_muchie(a, b, cap, cost);
}
cout << graf.afla_flux(S, D).second;
}
///-------------------------------------
inline void Output()
{
}
///-------------------------------------
int main()
{
#ifndef LOCAL
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
#endif
ReadInput();
Solution();
Output();
return 0;
}