Pagini recente » Cod sursa (job #2684791) | Istoria paginii utilizator/bonnetm412 | Diferente pentru teorema-chineza-a-resturilor intre reviziile 48 si 89 | Monitorul de evaluare | Cod sursa (job #962024)
Cod sursa(job #962024)
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int oo = 0x3f3f3f3f;
const int NIL = -1;
class Edge {
public:
int u, v, cost, capacity, flow;
Edge() {}
Edge(const int u, const int v, const int cost, const int capacity) {
this->u = u;
this->v = v;
this->cost = cost;
this->capacity = capacity;
this->flow = 0;
}
};
vector<vector<int>> G;
vector<Edge> Edges;
int V, E, Source, Sink;
vector<int> Father, Distance;
queue<int> Q;
vector<bool> InQ;
int Solution;
inline int NonEdge(const int e) {
if (e < E)
return e + E;
return e - E;
}
void InitializeBellmanFord(const int start) {
Father = vector<int>(V, NIL);
Distance = vector<int>(V, oo);
InQ = vector<bool>(V, false);
Distance[start] = 0;
Q.push(start);
InQ[start] = true;
}
bool BellmanFord(const int start, const int end) {
for (InitializeBellmanFord(start); !Q.empty(); Q.pop()) {
int x = Q.front();
InQ[x] = false;
if (x == end)
continue;
for (auto &e: G[x]) {
int y = Edges[e].v;
if (Edges[e].flow < Edges[e].capacity && Distance[x] + Edges[e].cost < Distance[y]) {
Father[y] = e;
Distance[y] = Distance[x] + Edges[e].cost;
if (!InQ[y]) {
Q.push(y);
InQ[y] = true;
}
}
}
}
return (Father[end] != NIL);
}
void InitializeNetwork(const int source, const int sink) {
Source = source;
Sink = sink;
for (int i = 0; i < E; ++i) {
Edges.push_back(Edge(Edges[i].v, Edges[i].u, -Edges[i].cost, 0));
G[Edges[i].v].push_back(NonEdge(i));
}
}
void MinCostMaxFlow(int &maxFlow, int &flowCost) {
maxFlow = flowCost = 0;
while (BellmanFord(Source, Sink)) {
int flow = oo;
for (int x = Sink; x != Source; x = Edges[Father[x]].u)
flow = min(flow, Edges[Father[x]].capacity - Edges[Father[x]].flow);
for (int x = Sink; x != Source; x = Edges[Father[x]].u) {
Edges[Father[x]].flow += flow;
Edges[NonEdge(Father[x])].flow -= flow;
}
maxFlow += flow;
flowCost += flow * Distance[Sink];
}
}
void Solve() {
int maxFlow, flowCost;
MinCostMaxFlow(maxFlow, flowCost);
Solution = flowCost;
}
inline void AddEdge(const int u, const int v, const int cost, const int capacity) {
Edges.push_back(Edge(u, v, cost, capacity));
G[u].push_back(E++);
}
void Read() {
ifstream in("fmcm.in");
int edges, source, sink;
in >> V >> edges >> source >> sink;
G = vector<vector<int>>(V, vector<int>());
for (; edges > 0; --edges) {
int u, v, cost, capacity;
in >> u >> v >> capacity >> cost;
AddEdge(u - 1, v - 1, cost, capacity);
}
InitializeNetwork(source - 1, sink - 1);
in.close();
}
void Print() {
ofstream out("fmcm.out");
out << Solution << "\n";
out.close();
}
int main() {
Read();
Solve();
Print();
return 0;
}