Pagini recente » Cod sursa (job #2895211) | Cod sursa (job #800460) | Cod sursa (job #2337004) | Cod sursa (job #1837593) | Cod sursa (job #2937366)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
const int NMAX = 300;
const int KMAX = 50;
const int GMAX = 300;
const int INF = 1e9;
int T;
int N, M;
int source, destination;
struct Edge {
int u, v, cap, cost, flow;
};
vector<Edge> edges;
vector<vector<int>> adj;
vector<int> potential;
vector<int> distHelper, dist;
vector<int> parent;
void addEdge(int u, int v, int cap, int cost, int flow = 0) {
int m = edges.size();
edges.push_back({u, v, cap, cost, flow});
edges.push_back({v, u, 0, -cost, 0});
adj[u].push_back(m);
adj[v].push_back(m + 1);
}
void bf() {
queue<int> q;
vector<bool> inQ(N + 1);
dist = vector<int> (N + 1, INF);
dist[source] = 0;
q.push(source);
inQ[source] = 1;
while(!q.empty()) {
int u = q.front();
q.pop();
inQ[u] = 0;
for(const auto &it: adj[u]) {
int v = edges[it].v;
int cap = edges[it].cap;
int cost = edges[it].cost;
int flow = edges[it].flow;
if(cap > 0 && dist[v] > dist[u] + cost) {
dist[v] = dist[u] + cost;
if(!inQ[v]) {
q.push(v);
inQ[v] = 1;
}
}
}
}
}
struct compare {
bool operator () (const int &u, const int &v) {
return distHelper[u] > distHelper[v];
}
};
bool dij() {
priority_queue<int, vector<int>, compare> pq;
vector<bool> inQ(N + 1);
parent = vector<int> (N + 1);
potential = dist;
dist = distHelper = vector<int> (N + 1, INF);
dist[source] = distHelper[source] = 0;
pq.push(source);
inQ[source] = 1;
while(!pq.empty()) {
int u = pq.top();
pq.pop();
inQ[u] = 0;
for(const auto &it: adj[u]) {
int v = edges[it].v;
int cap = edges[it].cap;
int cost = edges[it].cost;
int flow = edges[it].flow;
if(cap - flow > 0 && distHelper[v] + potential[v] > distHelper[u] + potential[u] + cost) {
distHelper[v] = distHelper[u] + potential[u] + cost - potential[v];
dist[v] = dist[u] + cost;
parent[v] = it;
if(!inQ[v]) {
pq.push(v);
inQ[v] = 1;
}
}
}
}
return distHelper[destination] != INF;
}
void solve() {
fin >> N >> M >> source >> destination;
edges = vector<Edge> (0);
adj = vector<vector<int>> (N + 1);
for(int i = 1; i <= M; i++) {
int u, v, c, z;
fin >> u >> v >> c >> z;
addEdge(u, v, c, z);
}
bf();
int maxFlow = 0, minCost = 0;
while(dij()) {
int flow = INF, cost = 0;
for(int u = destination; u != source; u = edges[parent[u]].u) {
flow = min(flow, edges[parent[u]].cap - edges[parent[u]].flow);
cost += edges[parent[u]].cost;
}
maxFlow += flow;
minCost += cost * flow;
for(int u = destination; u != source; u = edges[parent[u]].u) {
edges[parent[u]].flow += flow;
edges[parent[u] ^ 1].flow -= flow;
}
}
fout << minCost << '\n';
}
int main() {
ios_base :: sync_with_stdio(false);
solve();
return 0;
}