Pagini recente » Cod sursa (job #972698) | Cod sursa (job #1036039) | Cod sursa (job #244420) | Cod sursa (job #1288520) | Cod sursa (job #1937667)
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
const int NMAX = 355;
int N, M, Source, Dest, maxFlow = INT_MIN, Flow[NMAX][NMAX], Capacity[NMAX][NMAX], costMin;
int Cost[NMAX][NMAX], distBF[NMAX], DijDist[NMAX], realD[NMAX], Father[NMAX];
vector<int> G[NMAX];
void Read();
void BellmanFord();
void FMCM();
void Write() { cout << costMin << '\n'; }
int main() {
Read();
BellmanFord();
FMCM();
Write();
}
void Read() {
freopen("fmcm.in", "rt", stdin);
freopen("fmcm.out", "wt", stdout);
scanf("%d%d%d%d", &N, &M, &Source, &Dest);
while(M--) {
int u, v, cap, cost;
scanf("%d%d%d%d", &u, &v, &cap, &cost);
G[u].push_back(v); G[v].push_back(u);
Cost[u][v] = cost; Cost[v][u] = -cost;
Capacity[u][v] += cap;
}
}
void BellmanFord() {
for(int i = 0; i <= N; i++) distBF[i] = INT_MAX;
queue<int> Q; Q.push(Source); distBF[Source] = 0;
vector<bool> inQueue(N + 1, 0);
while(!Q.empty()) {
int node = Q.front();
Q.pop(); inQueue[node] = false;
for(int i = 0; i < G[node].size(); i++) {
int neigh = G[node][i];
if(!Capacity[node][neigh]) continue;
if(distBF[neigh] > distBF[node] + Cost[node][neigh]) {
distBF[neigh] = distBF[node] + Cost[node][neigh];
if(!inQueue[neigh]) {
Q.push(neigh); inQueue[neigh] = true;
}
}
}
}
}
void Dijkstra() {
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<pair<int, int> > > PQ;
for(int i = 0; i <= N; i++) DijDist[i] = INT_MAX, Father[i] = -1;
DijDist[Source] = realD[Source] = 0;
PQ.push(make_pair(0, Source));
while(!PQ.empty()) {
pair<int, int> top = PQ.top(); PQ.pop();
int node = top.second, d = top.first;
if(DijDist[node] < d) continue;
for(int i = 0; i < G[node].size(); i++) {
int neigh = G[node][i];
if(Capacity[node][neigh] > Flow[node][neigh]) {
int artificiu = Cost[node][neigh] + distBF[node] - distBF[neigh];
if(d + artificiu < DijDist[neigh]) {
DijDist[neigh] = d + artificiu;
PQ.push(make_pair(DijDist[neigh], neigh));
realD[neigh] = realD[node] + Cost[node][neigh];
Father[neigh] = node;
}
}
}
}
}
void FMCM() {
BellmanFord();
while(1) {
Dijkstra();
if(Father[Dest] == -1) break;
int mn = INT_MAX;
for(int node = Dest; node != Source; node = Father[node])
mn = min(mn, Capacity[Father[node]][node] - Flow[Father[node]][node]);
maxFlow += mn;
costMin += mn * realD[Dest];
for(int node = Dest; node != Source; node = Father[node])
Flow[Father[node]][node] += mn, Flow[node][Father[node]] -= mn;
for(int i = 0; i <= N; i++) distBF[i] = realD[i];
}
}