Pagini recente » Cod sursa (job #1171061) | Cod sursa (job #301308) | Cod sursa (job #1183426) | Cod sursa (job #35000) | Cod sursa (job #3155761)
//#define DEBUG
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
namespace std {
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
};
class flux {
private:
struct edge {
int pos;
int cost;
int flux;
int retid;
};
struct node {
std::vector <edge> edges;
};
std::vector <node> graph;
int source, destination;
struct path {
int pos;
int parid;
int cost;
bool operator<(const path &rhs) const {
return cost > rhs.cost; // smallest first
}
};
std::vector <int> mincost;
std::vector <int> prev;
bool findPath() {
std::priority_queue <path> next;
path now;
next.push({source, -1, 0});
bool found_end = false;
while (!next.empty()) {
now = next.top();
next.pop();
if (now.cost >= mincost[now.pos]) {
continue;
}
mincost[now.pos] = now.cost;
if (now.pos == destination) {
found_end = true;
}
prev[now.pos] = now.parid;
for (edge chd : graph[now.pos].edges) {
if (chd.flux > 0) {
next.push({chd.pos, chd.retid, now.cost + chd.cost});
}
}
}
return found_end;
}
int doPath() {
int nod = destination, edgeid;
int cost = 0;
while (nod != source) {
#ifdef DEBUG
std::cout << nod << ' ';
#endif
graph[nod].edges[prev[nod]].flux++;
cost -= graph[nod].edges[prev[nod]].cost;
edgeid = graph[nod].edges[prev[nod]].retid;
nod = graph[nod].edges[prev[nod]].pos;
graph[nod].edges[edgeid].flux--;
}
#ifdef DEBUG
std::cout << '\n' << cost << '\n';
#endif
return cost;
}
public:
flux(int size, int set_source, int set_destination) {
source = set_source;
destination = set_destination;
graph.resize(size);
mincost.resize(size, 0x7f7f7f7f);
prev.resize(size, 0);
}
void makeEdge(int par, int chd, int cost, int flux) {
graph[par].edges.push_back({chd, cost, flux, (int)graph[chd].edges.size()});
graph[chd].edges.push_back({par, -cost, 0, (int)graph[par].edges.size() - 1});
}
int doFlux() {
int ans = 0;
while (findPath()) {
ans += doPath();
memset(&mincost[0], 0x7f, mincost.size() * sizeof(int));
memset(&prev[0], 0x00, prev.size() * sizeof(int));
}
return ans;
}
};
int main() {
int n, m, s, d;
std::cin >> n >> m >> s >> d;
flux sol(n, --s, --d);
int nod, chd, flx, cost;
for (int i = 0; i < m; i++) {
std::cin >> nod >> chd >> flx >> cost;
sol.makeEdge(--nod, --chd, cost, flx);
}
std::cout << sol.doFlux();
}