Cod sursa(job #928566)
#include <fstream>
#include <vector>
#include <functional>
#include <cstring>
#include <queue>
#define pii pair<int,int>
using namespace std;
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
const int NMAX = 352, inf = int(1e9);
vector<int> G[NMAX];
int N, M, S, D;
int cap[NMAX][NMAX], cost[NMAX][NMAX];
int dist[3][NMAX], dLine, T[NMAX];
int flowCost, maxFlow;
bool inQueue[NMAX];
priority_queue< pii,vector< pii >,greater< pii > > h;
queue<int> q;
void readData() {
cin>>N>>M>>S>>D;
int a, b, c, d;
for(int i = 0;i < M;i++) {
cin>>a>>b>>c>>d;
G[a].push_back(b);
G[b].push_back(a);
cap[a][b] = c;
cost[a][b] = d;
cost[b][a] = -d;
}
}
bool bellman() {
for(int i = 1;i <= N;i++) {
dist[dLine][i] = inf;
}
dist[dLine][S] = 0;
for(q.push(S), inQueue[S] = true;!q.empty();) {
int v = q.front();
q.pop();
inQueue[v] = false;
for(vector<int>::const_iterator w = G[v].begin();w != G[v].end();w++) {
if(cap[v][*w] > 0 && dist[dLine][*w] > dist[dLine][v] + cost[v][*w]) {
dist[dLine][*w] = dist[dLine][v] + cost[v][*w];
if(!inQueue[*w]) {
inQueue[*w] = true;
q.push(*w);
}
}
}
}
if(dist[dLine][D] == inf) {
return false;
}
return true;
}
pii djikstra() {
dLine = 1 - dLine;
for(int i = 1;i <= N;i++) {
dist[dLine][i] = dist[2][i] = inf;
}
dist[dLine][S] = dist[2][S] = 0;
h.push(make_pair(0,S));
while(!h.empty()) {
int v = h.top().second;
int currentCost = h.top().first;
h.pop();
if(currentCost != dist[2][v]) continue;
for(vector<int>::const_iterator w = G[v].begin();w != G[v].end();w++) {
if(cap[v][*w] > 0 && dist[2][*w] > dist[2][v] + cost[v][*w] + dist[1 - dLine][v] - dist[1 - dLine][*w]) {
dist[2][*w] = dist[2][v] + cost[v][*w] + dist[1 - dLine][v] - dist[1 - dLine][*w];
T[*w] = v;
dist[dLine][*w] = dist[dLine][v] + cost[v][*w];
h.push(make_pair(dist[2][*w],*w));
}
}
}
if(dist[2][D] == inf) {
return make_pair(0,0);
}
int fmin = inf;
for(int v = D;v != S;v = T[v]) {
fmin = min(fmin,cap[T[v]][v]);
}
for(int v = D;v != S;v = T[v]) {
cap[T[v]][v] -= fmin;
cap[v][T[v]] += fmin;
}
return make_pair(fmin,fmin*dist[dLine][D]);
}
pii solve() { //flow,flow cost
pii ret, current;
ret.first = ret.second = 0;
if(bellman()) {
do {
current = djikstra();
ret.first += current.first;
ret.second += current.second;
} while(current.second != 0);
}
return ret;
}
int main()
{
readData();
cout<<solve().second;
return 0;
}