Pagini recente » Cod sursa (job #2364074) | Cod sursa (job #1617700) | Cod sursa (job #489867) | Cod sursa (job #3235092) | Cod sursa (job #1224196)
#include <fstream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N = 351, QSize = (1 << 9) - 1, inf = 0x3f3f3f3f;
class Queue{
int v[QSize + 1], st, dr;
bool use[N];
public:
Queue(){
st = dr = 0;
}
inline void push(int x){
if (!use[x]){
v[dr++] = x;
use[x] = true;
dr &= QSize;
}
}
inline int pop(){
int x = v[st++];
use[x] = false;
st &= QSize;
return x;
}
inline bool isEmpty(){
return st == dr;
}
};
struct Edge{
int y, c;
Edge(int y, int c) :
y(y),
c(c)
{}
};
int cf[N][N], dist[N], T[N], n;
vector<Edge> graph[N];
bool use[N];
Queue Q;
inline void relax(int x, int y, int F){
cf[x][y] -= F;
cf[y][x] += F;
}
bool bellmanFord(int x, int D){
memset(dist, inf, sizeof(dist));
dist[x] = 0;
Q.push(x);
while ( !Q.isEmpty() ){
x = Q.pop();
for (Edge E : graph[x])
if ( cf[x][E.y] && dist[x] + E.c < dist[E.y]){
dist[E.y] = dist[x] + E.c;
Q.push(E.y);
T[E.y] = x;
}
}
return dist[D] != inf;
}
bool dijkstra(int x, int D){
memset(dist, inf, sizeof(dist));
memset(use, false, sizeof(use));
dist[x] = 0;
do{
use[x] = true;
for (Edge E : graph[x])
if (cf[x][E.y] && dist[x] + E.c < dist[E.y]){
dist[E.y] = dist[x] + E.c;
T[E.y] = x;
}
x = 0;
for (int i = 1 ; i <= n ; i++)
if ( !use[i] && dist[i] < dist[x] )
x = i;
} while (x);
return dist[D] != inf;
}
int rebuildGraph(int S, int D){
bellmanFord(S, D);
for (int x = 1 ; x <= n ; x++)
for (auto it = graph[x].begin() ; it != graph[x].end() ; it++)
it -> c += dist[x] - dist[it -> y];
return dist[D];
}
int maxFlow(int S, int D){
int flow = 0, cost = 0, delta = rebuildGraph(S, D);
while ( dijkstra(S, D) ){
int F = inf;
for (int i = D ; i != S ; i = T[i])
F = min(F, cf[ T[i] ][i]);
for (int i = D ; i != S ; i = T[i])
relax(T[i], i, F);
cost += F * (delta + dist[D]);
flow += F;
}
return cost;
}
int main(){
ifstream in("fmcm.in");
int m, x, y, cap, cost, S, D;
in >> n >> m >> S >> D;
while (m--){
in >> x >> y >> cap >> cost;
cf[x][y] = cap;
graph[x].push_back( Edge(y, cost) );
graph[y].push_back( Edge(x, -cost) );
}
in.close();
ofstream out("fmcm.out");
out << maxFlow(S, D) << '\n';
out.close();
return 0;
}