Pagini recente » Cod sursa (job #1080199) | Cod sursa (job #590656) | Cod sursa (job #538387) | Cod sursa (job #398709) | Cod sursa (job #1238054)
#include <fstream>
#include <iostream>
#include <vector>
#include <bitset>
#include <string.h>
#include <algorithm>
#include <iomanip>
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include <set>
#include <map>
#include <string>
#include <queue>
#include <unordered_map>
using namespace std;
const char infile[] = "fmcm.in";
const char outfile[] = "fmcm.out";
ifstream fin(infile);
ofstream fout(outfile);
const int MAXN = 100005;
const int oo = 0x3f3f3f3f;
typedef vector<int> :: iterator It;
const inline int min(const int &a, const int &b) { if( a > b ) return b; return a; }
const inline int max(const int &a, const int &b) { if( a < b ) return b; return a; }
const inline void Get_min(int &a, const int b) { if( a > b ) a = b; }
const inline void Get_max(int &a, const int b) { if( a < b ) a = b; }
class Graph {
private:
vector <vector <pair<int, int> > > g;
unordered_map<int, unordered_map<int, int> > capacity, flow;
int N;
queue <int> q;
vector <bool> inq;
vector <int> dist, father;
public:
Graph() {
}
Graph(int N) {
this->N = N;
g.resize(N);
inq.resize(N);
dist.resize(N);
father.resize(N);
}
void addDirectedEdge(int x, int y, int cap, int cost) {
g[x].push_back(make_pair(y, cost));
capacity[x][y] = cap;
}
int getMinCostMaxFlow(int source, int sink) {
int mincostmaxflow = 0;
while(bellmanford(source, sink)) {
int bottleneck = oo;
for(int i = sink ; i != source ; i = father[i])
bottleneck = min(bottleneck, capacity[father[i]][i] - flow[father[i]][i]);
for(int i = sink ; i != source ; i = father[i]) {
flow[father[i]][i] += bottleneck;
flow[i][father[i]] -= bottleneck;
}
mincostmaxflow += bottleneck * dist[sink];
}
return mincostmaxflow;
}
bool bellmanford(int source, int sink) {
fill(dist.begin(), dist.end(), oo);
q.push(source);
inq[source] = true;
dist[source] = 0;
while(!q.empty()) {
int node = q.front();
q.pop();
inq[node] = false;
if(node == sink)
continue;
for(auto it:g[node])
if(dist[it.first] > dist[node] + it.second && capacity[node][it.first] - flow[node][it.first] > 0) {
dist[it.first] = dist[node] + it.second;
father[it.first] = node;
if(inq[it.first])
continue;
q.push(it.first);
inq[it.first] = true;
}
}
return dist[sink] != oo;
}
};
int N, M, S, D;
int main() {
fin >> N >> M >> S >> D;
Graph G(N);
for(int i = 1 ; i <= M ; ++ i) {
int x, y, cap, cost;
fin >> x >> y >> cap >> cost;
G.addDirectedEdge(x-1, y-1, cap, cost);
G.addDirectedEdge(y-1, x-1, 0,-cost);
}
fout << G.getMinCostMaxFlow(S - 1, D - 1) << '\n';
fin.close();
fout.close();
return 0;
}