Pagini recente » Cod sursa (job #1693069) | Cod sursa (job #373913) | Cod sursa (job #133841) | Cod sursa (job #1146984) | Cod sursa (job #1700727)
#include <fstream>
#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N = 1001, inf = 0x3f3f3f3f;
struct Edge{
int y, c;
Edge(int y, int c) : y(y), c(c) {};
inline bool operator<(const Edge& E) const {
return c > E.c;
}
};
vector<Edge> graph[N]; //bidirectional
int cap[N][N], diff[N][N], T[N], dist[N], bf_dist[N], n;
bool use[N];
bool dijkstra(int x, int D){
memset(dist, inf, sizeof(dist));
memset(use, false, sizeof(use));
memset(T, -1, sizeof(T));
priority_queue<Edge> Q;
Q.emplace(x, 0);
dist[x] = 0;
while ( !Q.empty() ){
x = Q.top().y;
Q.pop();
if ( x == D )
return true;
if ( use[x] )
continue;
use[x] = true;
for ( Edge e : graph[x] )
if ( diff[x][e.y] && dist[x] + e.c < dist[e.y] ){
dist[e.y] = dist[x] + e.c;
T[e.y] = x;
Q.emplace(e.y, dist[e.y]);
}
}
return false;
}
void prepare_graph(int* dist, int x){
memset(dist, inf, N * sizeof(*dist));
queue<int> Q;
dist[x] = 0;
Q.push(x);
// cerr << "Here?\n";
while ( !Q.empty() ){
x = Q.front();
Q.pop();
// cerr << x << ' ' << dist[x] << '\n';
for (Edge e : graph[x])
if ( cap[x][e.y] && dist[e.y] < dist[x] + e.c ){
dist[e.y] = dist[x] + e.c;
Q.push(e.y);
}
}
for (int x = 1; x <= n; x++)
for (Edge& e : graph[x])
e.c += dist[x] - dist[e.y];
}
int maxflow(int S, int D){
prepare_graph(bf_dist, S);
memcpy( diff, cap, sizeof(cap) );
int tot = 0;
while ( dijkstra(S, D) ) {
int F = inf;
for (int i = D; i != S; i = T[i])
F = min( F, diff[ T[i] ][i] );
for (int i = D; i != S; i = T[i]){
diff[ T[i] ][i] -= F;
diff[i][ T[i] ] += F;
}
tot += F;
}
return tot; //actual flow(x, y) = cap[x][y] - flow[x][y];
}
int get_cost(){
int cost = 0;
for (int x = 1; x <= n; x++)
for (Edge e : graph[x])
cost += (cap[x][e.y] - diff[x][e.y]) * (e.c + bf_dist[e.y] - bf_dist[x]);
return cost / 2;
}
int main(){
ifstream in("fmcm.in");
ofstream out("fmcm.out");
int S, D, m, x, y, c;
in >> n >> m >> S >> D;
while (m--){
in >> x >> y;
in >> cap[x][y] >> c;
graph[x].emplace_back(y, c);
graph[y].emplace_back(x, -c);
}
maxflow(S, D);
out << get_cost() << '\n';
return 0;
}