Pagini recente » Cod sursa (job #501097) | Cod sursa (job #1754464) | Cod sursa (job #2293247) | Cod sursa (job #282025) | Cod sursa (job #2009395)
#include <queue>
#include <vector>
#include <climits>
#include <iostream>
#include <fstream>
#include <bitset>
using namespace std;
ifstream in("fmcm.in");
ofstream out("fmcm.out");
int const nmax = 350;
struct Edge {
int to;
int rev;
int flow;
int cap;
int cost;
};
vector<Edge> g[1 + nmax];
struct Node {
int node;
int prio;
bool operator>(Node other) const {
return prio > other.prio;
}
};
int n, m, source, dest;
int dist[1 + nmax], prio[1 + nmax];
bitset<1 + nmax> vis;
int curflow[nmax], prevedge[nmax], prevnode[nmax];
void addedge(int from, int to, int cap, int cost) {
Edge dir = {to, (int) g[to].size(), 0, cap, cost};
Edge rev = {from, (int) g[from].size(), 0, 0, -cost};
g[from].push_back(dir);
g[to].push_back(rev);
}
void bellmanford() {
fill(dist + 1, dist + n + 1, INT_MAX);
dist[source] = 0;
queue<int> q;
q.push(source);
while (!q.empty()) {
int from = q.front();
vis[from] = 0;
q.pop();
for (int i = 0; i < (int) g[from].size(); i++) {
Edge &e = g[from][i];
if (e.flow < e.cap) {
int to = e.to;
int newdist = dist[from] + e.cost;
if (newdist < dist[to]) {
dist[to] = newdist;
if (vis[to] == 0) {
vis[to] = 1;
q.push(to);
}
}
}
}
}
}
void dijkstra() {
priority_queue<Node, vector<Node>, greater<Node> > q;
prio[source] = 0;
curflow[source] = INT_MAX;
q.push({source, prio[source]});
vis = 0;
while (!q.empty()) {
int from = q.top().node;
q.pop();
if (vis[from] == 0) {
vis[from] = 1;
for (int i = 0; i < (int) g[from].size(); i++) {
Edge &e = g[from][i];
int to = e.to;
if (e.flow < e.cap) {
int newprio = prio[from] + e.cost + dist[from] - dist[to];
if (newprio < prio[to]) {
prio[to] = newprio;
q.push({to, newprio});
prevnode[to] = from;
prevedge[to] = i;
curflow[to] = min(curflow[from], e.cap - e.flow);
}
}
}
}
}
}
void mincostflow(int &flow, int &flowcost) {
bellmanford();
flow = flowcost = 0;
while (prio[dest] < INT_MAX) {
fill(prio + 1, prio + n + 1, INT_MAX);
dijkstra();
if (prio[dest] < INT_MAX) {
for (int i = 1; i <= n; i++)
dist[i] += prio[i];
int df = curflow[dest];
flow += df;
for (int to = dest; to != source; to = prevnode[to]) {
Edge &e = g[prevnode[to]][prevedge[to]];
e.flow += df;
g[to][e.rev].flow -= df;
flowcost += df * e.cost;
}
}
}
}
int main() {
in >> n >> m >> source >> dest;
for (int i = 1; i <= m; i++) {
int from, to, cap, cost;
in >> from >> to >> cap >> cost;
addedge(from, to, cap, cost);
}
int flow, flowcost;
mincostflow(flow, flowcost);
out << flowcost << endl;
return 0;
}