Pagini recente » Cod sursa (job #3226300) | Cod sursa (job #3145031) | Cod sursa (job #2839539) | Cod sursa (job #3216280) | Cod sursa (job #2959747)
#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<int> G[NMAX];
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);
G[y].push_back(x);
capacity[x][y] = z;
cost[x][y] = c;
cost[y][x] = -c;
}
}
void BellmanFordFast(){
dist.assign(N + 1, INT_MAX);
//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 : G[node]){
if(capacity[node][next] > 0 && dist[node] + cost[node][next] < dist[next]){
dist[next] = dist[node] + cost[node][next];
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 : 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;
}