Pagini recente » Clasament Teme Pregatire ACM Unibuc 2014, Anul II | Cod sursa (job #2689626)
#include <bits/stdc++.h>
using namespace std;
struct Graph{
int n, s, d;
vector < vector <int> > graph;
vector < vector <int> > cap, cost;
vector <int> cost_dist, flux_dist, pr;
queue <int> Q;
priority_queue < pair <int, int> > S;
vector <bool> vis;
Graph(int _n, int _s, int _d): n(_n), s(_s), d(_d), graph(n),
cap(n, vector<int>(n)), cost(cap), cost_dist(n),
flux_dist(n), pr(n), vis(n) { }
void AddEdge(int a, int b, int cp, int cst){
graph[a].push_back(b);
graph[b].push_back(a);
cap[a][b] += cp;
cost[a][b] += cst;
cost[b][a] -= cst;
}
void Bellman(){
fill(cost_dist.begin(), cost_dist.end(), 1e9);
fill(vis.begin(), vis.end(), 0);
Q.push(s);
cost_dist[s] = 0;
vis[s] = 1;
while (not Q.empty()){
int node = Q.front();
Q.pop();
vis[node] = 0;
int curr_cost = cost_dist[node];
for (int nei: graph[node]){
if (!cap[node][nei])
continue;
int new_dist = curr_cost + cost[node][nei];
if (new_dist < cost_dist[nei]){
cost_dist[nei] = new_dist;
if (!vis[nei]){
vis[nei] = 1;
Q.push(nei);
}
}
}
}
}
int Dijkstra(){
fill(flux_dist.begin(), flux_dist.end(), 1e9);
vector <int> aux(n, 1e9);
S.push({0, s});
flux_dist[s] = 0;
aux[s] = 0;
while (not S.empty()){
int curr_cost = -S.top().first;
int node = S.top().second;
S.pop();
if (curr_cost != flux_dist[node])
continue;
for (int nei: graph[node]){
if (!cap[node][nei])
continue;
int new_dist = curr_cost + cost[node][nei] + cost_dist[node] - cost_dist[nei];
if (new_dist < flux_dist[nei]){
flux_dist[nei] = new_dist;
S.push({-flux_dist[nei], nei});
pr[nei] = node;
aux[nei] = aux[node] + cost[node][nei];
}
}
}
if (flux_dist[d] == 1e9)
return 0;
int flow = 1e9;
for (int node = d; node != s; node = pr[node])
flow = min(flow, cap[pr[node]][node]);
for (int node = d; node != s; node = pr[node]){
cap[pr[node]][node] -= flow;
cap[node][pr[node]] += flow;
}
cost_dist = aux;
return cost_dist[d] * flow;
}
int MinCostMaxFlow(){
Bellman();
int ans = 0;
while (auto lol = Dijkstra())
ans += lol;
return ans;
}
};
int main(){
ifstream cin("fmcm.in");
ofstream cout("fmcm.out");
int n, m, s, d;
cin >> n >> m >> s >> d;
s--; d--;
Graph G(n, s, d);
while (m--){
int a, b, c, z;
cin >> a >> b >> c >> z;
a--; b--;
G.AddEdge(a, b, c, z);
}
cout << G.MinCostMaxFlow() << '\n';
return 0;
}