Pagini recente » Cod sursa (job #1369219) | Cod sursa (job #1371498) | Cod sursa (job #2630217) | Cod sursa (job #1072526) | Cod sursa (job #2966039)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
template<class obj>
class heap {
private:
struct nod {
obj val;
nod* down, * next;
nod(obj val) {
this->val = val;
down = next = NULL;
}
};
nod* root, * aux;
inline nod* unit(nod* a, nod* b) {
if (a == NULL)
return b;
if (b == NULL)
return a;
if (!(a->val < b->val))
swap(a, b);
b->next = a->down;
a->down = b;
return a;
}
inline nod* convert(nod* x) {
if (x == NULL || x->next == NULL)
return x;
nod* next1 = x->next;
nod* next2 = next1->next;
return unit(unit(x, next1), convert(next2));
}
public:
inline heap() {
root = NULL;
}
inline void add(obj val) {
root = unit(root, new nod(val));
}
inline obj top() {
return root->val;
}
inline bool empty() {
return root == NULL;
}
inline void pop() {
aux = convert(root->down);
delete(root);
root = aux;
}
inline void clear() {
root = NULL;
}
};
int d[351];
struct nod {
short x;
int val;
bool operator < (nod& aux) {
return d[x] < d[aux.x];
}
};
heap <nod> H;
typedef long long ll;
vector <int> g[351];
int cost[351][351], flow[351][351], aux[351], t[351];
const int inf = 1000000000;
int n, m, src, dest;
bitset <351> inQ;
// Bellman-Ford
void generate()
{
for (int i = 1; i <= n; i++)
aux[i] = inf;
aux[src] = 0;
queue <int> Q;
Q.push(src);
inQ[src] = true;
while (!Q.empty())
{
int nod = Q.front();
Q.pop();
inQ[nod] = false;
for (auto& i : g[nod])
if (flow[nod][i] && aux[i] > aux[nod] + cost[nod][i])
{
aux[i] = aux[nod] + cost[nod][i];
Q.push(i);
if (!inQ[i])
inQ[i] = true;
}
}
}
// dijkstra
inline bool djk()
{
H.clear();
memset(d, 0x3f3f3f3f, sizeof(d));
d[src] = 0;
H.add({ (short)src, 0});
int val, x, cst;
vector <int>::iterator i;
while (!H.empty())
{
x = H.top().x, cst = H.top().val;
H.pop();
if (cst != d[x])
continue;
if (x == dest)
return true;
for (i = g[x].begin(); i != g[x].end(); i++)
{
val = d[x] + cost[x][*i] + aux[x] - aux[*i];
if (flow[x][*i] && d[*i] > val)
{
d[*i] = val;
H.add({ (short)*i, d[*i] });
t[*i] = x;
}
}
}
return false;
}
// minim cost for maxim flow
inline int minCost()
{
int res = 0;
while (djk())
{
int x = dest;
int mini = inf;
while (x != src)
{
if (flow[t[x]][x] < mini)
mini = flow[t[x]][x];
x = t[x];
}
res += (d[dest] + aux[dest]) * mini;
x = dest;
while (x != src)
{
flow[t[x]][x] -= mini;
flow[x][t[x]] += mini;
x = t[x];
}
}
return res;
}
int main()
{
fin >> n >> m >> src >> dest;
for (int i = 1; i <= m; i++)
{
int x, y;
fin >> x >> y;
fin >> flow[x][y] >> cost[x][y];
cost[y][x] = -cost[x][y];
g[x].push_back(y);
g[y].push_back(x);
}
generate();
fout << minCost();
return 0;
}