Pagini recente » Cod sursa (job #79759) | Cod sursa (job #296689) | Cod sursa (job #2248678) | Cod sursa (job #338251) | Cod sursa (job #2959742)
#include <bits/stdc++.h>
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
const int NMAX = 355;
int N, M, S, D;
vector<pair<int, int>> G[NMAX]; // graph with costs
vector<vector<int>> capacity(NMAX, vector<int> (NMAX, 0));
vector<vector<int>> cost(NMAX, vector<int> (NMAX, 0));
vector<int> dist(NMAX, 0);
void read(){
f >> N >> M >> S >> D;
for(int i = 1; i <= M; ++i){
int x, y, z, c;
f >> x >> y >> z >> c;
G[x].push_back({y, c});
capacity[x][y] = z;
cost[x][y] = c;
cost[y][x] = -c;
}
}
void BellmanFordFast(){
dist.assign(N + 1, 0);
//vector<int> cnt(N, 0);
vector<bool> in_queue(N + 1, false);
queue<int> Q;
dist[S] = 0;
in_queue[S] = true;
Q.push(S);
while(!Q.empty()){
int node = Q.front();
Q.pop();
in_queue[node] = false;
for(auto& [next, cst] : G[node]){
if(dist[node] + cst < dist[next]){
dist[next] = dist[node] + cst;
if(!in_queue[next]){
Q.push(next);
in_queue[next] = true;
//++cnt[next];
//if(cnt[next] > N)
// return false; // negative cycle
}
}
}
}
//return true;
}
bool Dijkstra(vector<int>& parent){
vector<int> aux_dist(N + 1, INT_MAX), real_dist(N + 1, INT_MAX);
priority_queue<pair<int, int>> PQ;
parent[S] = -1;
aux_dist[S] = real_dist[S] = 0;
PQ.push({0, S});
while(!PQ.empty()){
int node_cst = PQ.top().first;
int node = PQ.top().second;
PQ.pop();
if(aux_dist[node] != node_cst)
continue;
for(auto& [next, next_cst] : G[node]){
if(capacity[node][next] > 0){
int temp_dist = aux_dist[node] +
cost[node][next] +
dist[node] - dist[next];
if(temp_dist < aux_dist[next]){
aux_dist[next] = temp_dist;
real_dist[next] = real_dist[node] + cost[node][next];
parent[next] = node;
PQ.push({aux_dist[next], next});
}
}
}
}
for(int i = 1; i <= N; ++i)
dist[i] = real_dist[i];
return (aux_dist[D] != INT_MAX);
}
void solve(){
int max_flow = 0, min_cost = 0;
vector<int> parent(NMAX, -1);
BellmanFordFast(); // initialize
while(Dijkstra(parent)){
int path_flow = INT_MAX, path_cost = 0;
// find the max flow through the path
for(int node = D; node != S; node = parent[node]){
int aux = parent[node];
path_flow = min(path_flow, capacity[aux][node]);
path_cost += cost[aux][node];
}
//if(path_flow == 0) continue;
// update
for(int node = D; node != S; node = parent[node]){
int aux = parent[node];
capacity[aux][node] -= path_flow;
capacity[node][aux] += path_flow;
}
max_flow += path_flow;
min_cost += path_flow * path_cost;
}
g << min_cost << '\n';
}
int main(){
read();
solve();
return 0;
}