Pagini recente » Cod sursa (job #1426326) | Cod sursa (job #3127211) | Cod sursa (job #2875426) | Cod sursa (job #1894304) | Cod sursa (job #2462470)
#include <fstream>
#include <vector>
#include <queue>
#include <cstring>
using namespace std;
ifstream f("fmcm.in");
ofstream g("fmcm.out");
const int NMax = 355;
int N, M, S, Dest;
int D[355];
vector <pair <int, int> > G[NMax];
int Cap[30005], F[30005], Cost[30005], Rev[30005];
pair <int, int> E[30005];
int e;
pair <int, int> TT[30005];
bool InQ[355], Used[355];
int Dist[355], realD[355];
queue <int> Q;
priority_queue <pair <int, int>, vector <pair <int, int> >, greater <pair <int, int> > > PQ;
void addEdge(int x, int y, int cap, int cost){
++e;
E[e] = make_pair(x, y);
Rev[e] = e + 1;
G[x].push_back(make_pair(y, e));
Cost[e] = cost;
Cap[e] = cap;
F[e] = 0;
++e;
E[e] = make_pair(y, x);
Rev[e] = e - 1;
G[y].push_back(make_pair(x, e));
Cost[e] = -cost;
Cap[e] = 0;
F[e] = 0;
}
void Read(){
f >> N >> M >> S >> Dest;
for(int i = 1; i <= M; i++){
int x, y, cap, cost;
f >> x >> y >> cap >> cost;
addEdge(x, y, cap, cost);
}
}
void bellmanFord(int source){
for(int i = 1; i <= N; i++)
Dist[i] = 1000000005;
Q.push(source);
InQ[source] = 1;
Dist[source] = 0;
while(!Q.empty()){
int node = Q.front();
Q.pop();
InQ[node] = 0;
for(int i = 0; i < G[node].size(); i++){
int neighb = G[node][i].first, cost = Cost[G[node][i].second];
if(Dist[neighb] > Dist[node] + cost && Cap[G[node][i].second] != 0){
Dist[neighb] = Dist[node] + cost;
if(!InQ[neighb])
Q.push(neighb);
InQ[neighb] = 1;
}
}
}
}
bool Dijkstra(int source){
for(int i = 1; i <= N; i++){
D[i] = 1000000000;
TT[i] = make_pair(-1, -1);
//realD[i] = D[i];
}
D[source] = realD[source] = 0;
PQ.push(make_pair(0, S));
while(!PQ.empty()){
int node = PQ.top().second, d = PQ.top().first;
PQ.pop();
if(d > D[node])
continue;
for(int i = 0; i < G[node].size(); i++){
int neighb = G[node][i].first, e = G[node][i].second;
if(Cap[e] - F[e] == 0)
continue;
int cost = Cost[e] + Dist[node] - Dist[neighb];
if(D[node] + cost < D[neighb]){
D[neighb] = D[node] + cost;
realD[neighb] = realD[node] + Cost[e];
TT[neighb] = make_pair(node, e);
PQ.push(make_pair(D[neighb], neighb));
}
}
}
return TT[Dest] != make_pair(-1, -1);
}
void Solve(){
int flow = 0;
long long cost = 0;
while(Dijkstra(S)){
int Min = 2000000005;
for(int i = Dest; i != S; i = TT[i].first){
int e = TT[i].second;
Min = min(Min, Cap[e] - F[e]);
}
cost += Min * realD[Dest];
for(int i = Dest; i != S; i = TT[i].first){
int e = TT[i].second, rev = Rev[e];
F[e] += Min;
F[rev] -= Min;
}
memcpy(Dist, realD, sizeof(realD));
}
g << cost << '\n';
}
int main()
{
Read();
bellmanFord(S);
Solve();
return 0;
}