Pagini recente » Cod sursa (job #2584724) | Cod sursa (job #1418556) | Cod sursa (job #1654206) | Cod sursa (job #2982017) | Cod sursa (job #2900247)
/// always:
#include <cstdio>
#include <string>
/// optional:
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>
#include <iomanip>
#include <algorithm>
#include <queue>
bool home = 1;
using namespace std;
typedef long long ll;
const string TASKNAME="fmcm";
const int FN=350+7;
const int FM=12500+7;
const int INF=(int)1e9+7;
struct Edge {
int to;
int cap;
int cost;
};
int fn,fm,fs,fd,best[FN],pare[FN];
bool inq[FN];
vector<int> g[FN];
Edge edges[FM];
void init(int n,int s,int d) {
for (int i=1;i<=n;i++) g[i].clear();
fn=n;
fm=0;
fs=s;
fd=d;
assert(1<=fs&&fs<=n);
assert(1<=fd&&fd<=n);
}
void addEdge(int a,int b,int cap,int cost) {
assert(1<=a&&a<=fn);
assert(1<=b&&b<=fn);
g[a].push_back(fm);
g[b].push_back(fm+1);
edges[fm++]={b, cap, cost};
edges[fm++]={a, 0, -cost};
}
void bellman() {
for (int i=1;i<=fn;i++) {
best[i]=INF;
inq[i]=0;
}
best[fs]=0;
inq[fs]=1;
queue<int> q;
q.push(fs);
while (!q.empty()) {
int a=q.front();
inq[a]=0;
q.pop();
for (auto &i:g[a]) {
int b=edges[i].to;
int cap=edges[i].cap;
int cost=edges[i].cost;
if (cap>0&&best[a]+cost<best[b]) {
best[b]=best[a]+cost;
pare[b]=i;
if (inq[b]==0) inq[b]=1, q.push(b);
}
}
}
}
pair<ll, ll> get() {
ll flow=0;
ll cost=0;
while (1) {
bellman();
if (best[fd]==INF) break;
int cap=INF;
vector<int> path;
int cur=fd;
while (cur!=fs) {
path.push_back(pare[cur]);
cap=min(cap,edges[pare[cur]].cap);
assert(edges[pare[cur]].to==cur);
cur=edges[pare[cur]^1].to;
}
assert(cap>0);
flow+=cap;
cost+=best[fd]*(ll)cap;
for (auto &i:path){
assert(edges[i].cap-cap>=0);
edges[i].cap-=cap;
edges[i^1].cap+=cap;
}
}
return {flow, cost};
}
signed main() {
#ifdef INFOARENA
home = 0;
#endif
if(!home) {
freopen((TASKNAME + ".in").c_str(), "r", stdin);
freopen((TASKNAME + ".out").c_str(), "w", stdout);
}else{
freopen ("I_am_iron_man", "r", stdin);
}
int n,m,s,d;
cin>>n>>m>>s>>d;
init(n,s,d);
for (int i=1;i<=m;i++) {
int a,b,c,d;
cin>>a>>b>>c>>d;
addEdge(a,b,c,d);
}
cout<<get().second<<"\n";
}