Pagini recente » Cod sursa (job #772383) | Cod sursa (job #3183511) | Cod sursa (job #3207171) | Cod sursa (job #576292) | Cod sursa (job #2961127)
#include <vector>
#include <queue>
#include <fstream>
#include <climits>
#include <iostream>
using namespace std;
ifstream fileIn("fmcm.in");
ofstream fileOut("fmcm.out");
class MaxFlowMinCost {
int N;
int M;
int S;
int D;
vector<int> distance;
vector<int> prev_in_bfs;
vector<vector<int>> list_adj;
vector<vector<int>> capacities;
vector<vector<int>> costs;
public:
void read();
void initialize(int k, int initial_capacity = 0);
int bellman_ford(int& source, int& target);
int maxflow_mincost();
};
void MaxFlowMinCost::initialize(int k, int initial_capacity) {
list_adj.resize(k);
distance.resize(k, INT_MAX);
prev_in_bfs.resize(k, -1);
capacities.resize(k);
costs.resize(k);
for(int i = 0; i < (int) capacities.size(); ++i) {
capacities[i].resize(k, 0);
costs[i].resize(k, 0);
}
}
void MaxFlowMinCost::read() {
fileIn >> N >> M >> S >> D;
initialize(N + 1);
int a, b, c, d; // c capacitate, d cost
for( int i = 1; i <= M; i++) {
fileIn >> a >> b >> c >> d;
list_adj[a].push_back(b);
list_adj[b].push_back(a);
capacities[a][b] = c;
costs[a][b] = d;
costs[b][a] = -d;
}
}
int MaxFlowMinCost::bellman_ford(int &source, int &target) {
distance.clear();
distance.resize(N + 1, INT_MAX);
vector<bool> inQueue(N + 1, false);
queue<int> q;
q.push(source);
distance[source] = 0;
prev_in_bfs[source] = source;
inQueue[source] = true;
while (!q.empty()) {
int node = q.front();
q.pop();
inQueue[node] = false;
for (auto neigh: list_adj[node]) {
if (capacities[node][neigh] > 0 && distance[neigh] > distance[node] + costs[node][neigh]) {
distance[neigh] = distance[node] + costs[node][neigh];
prev_in_bfs[neigh] = node;
if (!inQueue[neigh]) {
inQueue[neigh] = true;
q.push(neigh);
}
}
}
}
int curr_flow = INT_MAX;
if (distance[target]) {
for(int curr_node = D; curr_node != S; curr_node = prev_in_bfs[curr_node]) {
curr_flow = min(curr_flow, capacities[prev_in_bfs[curr_node]][curr_node]);
}
for(int curr_node = D; curr_node != S; curr_node = prev_in_bfs[curr_node]) {
capacities[curr_node][prev_in_bfs[curr_node]] += curr_flow;
capacities[prev_in_bfs[curr_node]][curr_node] -= curr_flow;
}
}
return curr_flow;
}
int MaxFlowMinCost::maxflow_mincost() {
int maxflow = 0;
int bottleneck = bellman_ford(S, D);
while(bottleneck != 0) { // while i still can find a path with flow on it
maxflow += bottleneck * distance[D];
bottleneck = bellman_ford(S, D);
}
return maxflow;
}
int main() {
MaxFlowMinCost fmcm;
fmcm.read();
fileOut << fmcm.maxflow_mincost();
return 0;
}