Pagini recente » Cod sursa (job #66080) | Cod sursa (job #1421414) | Cod sursa (job #762848) | Cod sursa (job #541485) | Cod sursa (job #1700733)
#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 dijkstra(int x, int D){
memset(dist, inf, sizeof(dist));
memset(T, -1, sizeof(T));
priority_queue<Edge> Q;
Q.emplace(x, 0);
dist[x] = 0;
while ( !Q.empty() ){
x = Q.top().y;
int c = Q.top().c;
Q.pop();
if ( x == D ) return true;
if ( dist[x] != c ) continue;
// cerr << x << ' ' << c << '\n';
for ( Edge e : graph[x] ) {
c = dist[x] + e.c + bf_dist[x] - bf_dist[e.y];
if ( diff[x][e.y] && c < dist[e.y] ){
Q.emplace(e.y, c);
dist[e.y] = c;
T[e.y] = x;
}
}
}
return false;
}
char q[5];
void prepare_graph(int* dist, int x){
memset(dist, inf, N * sizeof(*dist));
queue<int> Q;
dist[x] = 0;
Q.push(x);
while ( !Q.empty() ){
x = Q.front();
Q.pop();
for (Edge e : graph[x])
if ( cap[x][e.y] && dist[x] + e.c < dist[e.y] ){
dist[e.y] = dist[x] + e.c;
Q.push(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 += e.c * (cap[x][e.y] - diff[x][e.y]);
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;
}