Pagini recente » Cod sursa (job #1102457) | Cod sursa (job #1666104) | Cod sursa (job #284115) | Cod sursa (job #2374795) | Cod sursa (job #2931175)
#include <fstream>
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
const int maxN = 355, inf = 0x3f3f3f3f;
int n, m, sursa, dest;
int fake_dist[maxN], real_dist[maxN], prv[maxN], total_cost, dist[maxN];
bool used[maxN];
struct muchie {
int nxt, flux, cap, cost;
}lm[25005];
vector <int> G[maxN];
struct haha4heap {
int nod, cost;
bool operator < (const haha4heap &other) const {
return cost > other.cost;
}
};
priority_queue <haha4heap> heap;
queue <int> q;
void bellman_ford()
{
for(int i = 1; i <= n; i++)
dist[i] = inf;
dist[sursa] = 0;
q.push(sursa);
while(!q.empty())
{
int curr = q.front();
q.pop();
for(int ind : G[curr])
{
muchie aux = lm[ind];
if(aux.cap == 0 || dist[curr] + aux.cost >= dist[aux.nxt])
continue;
dist[aux.nxt] = dist[curr] + aux.cost;
q.push(aux.nxt);
}
}
}
bool dijkstra()
{
for(int i = 1; i <= n; i++)
{
fake_dist[i] = inf;
real_dist[i] = dist[i];
used[i] = 0;
}
while(!heap.empty())
heap.pop();
fake_dist[sursa] = 0;
dist[sursa] = 0;
heap.push({sursa, 0});
while(!heap.empty())
{
int curr = heap.top().nod;
heap.pop();
if(used[curr])
continue;
used[curr] = 1;
for(int ind : G[curr])
{
muchie aux = lm[ind];
if(aux.flux < aux.cap && fake_dist[curr] + aux.cost + real_dist[curr] - real_dist[aux.nxt] < fake_dist[aux.nxt])
{
prv[aux.nxt] = ind;
fake_dist[aux.nxt] = fake_dist[curr] + aux.cost + real_dist[curr] - real_dist[aux.nxt];
dist[aux.nxt] = dist[curr] + aux.cost;
heap.push({aux.nxt, fake_dist[aux.nxt]});
}
}
}
if(fake_dist[dest] == inf)
return 0;
return 1;
}
int main()
{
fin >> n >> m >> sursa >> dest;
for(int i = 0; i < m; i++)
{
int x, y, c, cst;
fin >> x >> y >> c >> cst;
lm[2 * i] = {y, 0, c, cst};
lm[2 * i + 1] = {x, 0, 0, -cst};
G[x].push_back(2 * i);
G[y].push_back(2 * i + 1);
}
bellman_ford();
while(dijkstra())
{
int min_flow = inf;
for(int x = dest; x != sursa; x = lm[prv[x] ^ 1].nxt)
min_flow = min(min_flow, lm[prv[x]].cap - lm[prv[x]].flux);
for(int x = dest; x != sursa; x = lm[prv[x] ^ 1].nxt)
{
lm[prv[x]].flux += min_flow;
lm[prv[x] ^ 1].flux -= min_flow;
}
total_cost += min_flow * dist[dest];
}
fout << total_cost;
return 0;
}