Pagini recente » Cod sursa (job #1161112) | Cod sursa (job #2845165) | Cod sursa (job #3240854) | Cod sursa (job #1428287) | Cod sursa (job #1439240)
#include <iostream>
#include <fstream>
#include <vector>
#include <functional>
#include <cstring>
#include <queue>
#include <limits>
using namespace std;
class MinCostMaxFlow {
vector< vector<int> > dist, cap, cost, graph;
vector<bool> inQueue;
vector<int> T;
int source, sink, N, distLine;
const int inf = numeric_limits<int>::max();
public:
void addEdge(int x, int y,int z, int c) {
cost[x][y] = z;
cost[y][x] = -z;
graph[x].push_back(y);
graph[y].push_back(x);
cap[x][y] = c;
}
MinCostMaxFlow(int n, int s, int S) {
N = n;
source = s;
sink = S;
dist.resize(3, vector<int>(N));
distLine = 0;
cap.resize(N, vector<int>(N));
cost = cap;
graph.resize(N);
T.resize(N);
inQueue.resize(N);
}
bool bellman() {
queue<int> Q;
for(int i = 0;i < N;i++) {
dist[distLine][i] = inf;
}
dist[distLine][source] = 0;
Q.push(source);
inQueue[source] = true;
while (!Q.empty()) {
int v = Q.front();
Q.pop();
inQueue[v] = false;
for (int& w : graph[v]) {
if(cap[v][w] > 0 && dist[distLine][w] > dist[distLine][v] + cost[v][w]) {
dist[distLine][w] = dist[distLine][v] + cost[v][w];
if (!inQueue[w]) {
inQueue[w] = true;
Q.push(w);
}
}
}
}
if(dist[distLine][sink] == inf) {
return false;
}
return true;
}
pair<int,int> djikstra() {
distLine = 1 - distLine;
for(int i = 0; i < N;i++) {
dist[distLine][i] = inf;
dist[2][i] = inf;
}
priority_queue< pair<int,int> > h;
dist[distLine][source] = dist[2][source] = 0;
h.push(make_pair(0,source));
while (!h.empty()) {
int v = h.top().second;
int currentCost = -h.top().first;
h.pop();
if(currentCost != dist[2][v]) continue;
for (int& w : graph[v]) {
if(cap[v][w] > 0 && dist[2][w] > dist[2][v] + cost[v][w] + dist[1 - distLine][v] - dist[1 - distLine][w]) {
dist[2][w] = dist[2][v] + cost[v][w] + dist[1 - distLine][v] - dist[1 - distLine][w];
T[w] = v;
dist[distLine][w] = dist[distLine][v] + cost[v][w];
h.push(make_pair(-dist[2][w], w));
}
}
}
if (dist[2][sink] == inf) {
return make_pair(0,0);
}
int fmin = inf;
for (int v = sink;v != source;v = T[v]) {
fmin = min(fmin,cap[T[v]][v]);
}
for (int v = sink;v != source;v = T[v]) {
cap[T[v]][v] -= fmin;
cap[v][T[v]] += fmin;
}
return make_pair(fmin,fmin*dist[distLine][sink]);
}
pair<int,int> solve() { //flow,flow cost
pair<int,int> 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()
{
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int n, m, s, d, a, b, c;
cin >> n >> m >> s >> d;
s--, d--;
MinCostMaxFlow solver(n, s, d);
for (int i = 0; i < m; i++) {
cin >> a >> b >> c >> d;
a--, b--;
solver.addEdge(a, b, d, c);
}
pair<int,int> ans = solver.solve();
cout << ans.second;
return 0;
}