Pagini recente » Cod sursa (job #2706671) | Cod sursa (job #288768) | Cod sursa (job #252856) | Cod sursa (job #444325) | Cod sursa (job #2011000)
#include <fstream>
#include <vector>
#include <queue>
#include <climits>
#include <algorithm>
#include <bitset>
using namespace std;
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int const nmax = 350;
struct Node {
int node;
int p;
bool operator>(Node other) const{
return (p > other.p);
}
};
struct Edge{
int to;
int rev;
int cost;
int cap;
int flow;
};
vector <Edge> g[1 + nmax];
int n, m, src, dest;
int dist[1 + nmax], distdij[1 + nmax];
bitset<1 + nmax> vis;
int prevnode[1 + nmax], prevedge[1 + nmax], plusflow[1 + nmax];
void bellmanford() {
queue <int> q;
fill(dist + 1, dist + n + 1, INT_MAX);
dist[src] = 0;
q.push(src);
while(!q.empty()) {
int u = q.front();
for(int k = 0; k < g[u].size(); ++ k) {
if(0 < g[u][k].cap) {
int v = g[u][k].to, c = g[u][k].cost;
if(dist[u] + c < dist[v]) {
q.push(v);
dist[v] = dist[u] + c;
}
}
}
q.pop();
}
}
void dijkstra() {
fill(distdij + 1, distdij + n + 1, INT_MAX);
priority_queue <Node, vector<Node>, greater<Node> > pq;
vis = 0;
distdij[src] = 0;
pq.push({src, 0});
vis[src] = 1;
plusflow[src] = INT_MAX;
while(!pq.empty()) {
int from = pq.top().node;
for(int k = 0; k < g[from].size(); ++ k) {
Edge &e = g[from][k];
int to = e.to;
if(vis[to] == 0 && e.flow < e.cap) {
int newdistdij = distdij[from] + e.cost + dist[from] - dist[to];
if(newdistdij < distdij[to]) {
distdij[to] = newdistdij;
pq.push({to, distdij[to]});
vis[to] = 1;
prevnode[to] = from;
prevedge[to] = k;
plusflow[to] = min(plusflow[from], e.cap - e.flow);
}
}
}
pq.pop();
}
}
void mincostflow(int &flow, int &flowcost) {
flow = flowcost = 0;
bellmanford();
while(distdij[dest] < INT_MAX) {
dijkstra();
if(distdij[dest] < INT_MAX) {
int deltaflow = plusflow[dest];
flow += deltaflow;
for(int to = dest; to!= src; to = prevnode[to]) {
Edge &e = g[prevnode[to]][prevedge[to]];
e.flow += deltaflow;
g[e.to][e.rev].flow -= deltaflow;
flowcost += deltaflow * e.cost;
}
}
for(int i = 1; i <= n; ++ i) {
dist[i] += distdij[i];
}
}
}
int main() {
cin >> n >> m >> src >> dest;
for(int i = 1; i <= m; ++ i) {
int x, y, c, z;
cin >> x >> y >> c >> z;
g[x].push_back({y, g[y].size(), z, c, 0});
g[y].push_back({x, g[x].size() - 1, -z, 0, 0});
}
int flow, flowcost;
mincostflow(flow, flowcost);
cout << flowcost;
return 0;
}