Pagini recente » Cod sursa (job #2367648) | Cod sursa (job #3201264) | Cod sursa (job #1174431) | Cod sursa (job #2034020) | Cod sursa (job #867323)
Cod sursa(job #867323)
#include <fstream>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
#define PII pair<int, int>
#define nmax 360
#define inf 0x3f3f3f3f
#define mp make_pair
#define pb push_back
vector<PII> G[nmax];
bool InQueue[nmax];
int N, M, X, Y, C, S, D, Z, Dist[nmax], Sum, Heap[nmax], Pos[nmax], L;
int Capacity[nmax][nmax], CurrentFlow[nmax][nmax], Father[nmax];
void BellmanFord()
{
int node, i;
for(i = 1; i <= N; i++) Dist[i] = inf;
Dist[S] = 0;
queue<int> Q;
InQueue[S] = 1;
Q.push(S);
while(!Q.empty())
{
node = Q.front();
Q.pop();
InQueue[node] = false;
for(vector<PII> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
if(Dist[it -> first] > Dist[node] + it -> second)
if(Capacity[node][it -> first] > CurrentFlow[node][it -> first])
{
Dist[it -> first] = Dist[node] + it -> second;
if(!InQueue[it -> first])
{
InQueue[it -> first] = 1;
Q.push(it -> first);
}
}
}
}
void Update()
{
int i, j;
for(i = 1; i <= N; i++)
for(vector<PII> :: iterator it = G[i].begin(); it != G[i].end(); ++it)
it -> second += Dist[i] - Dist[it -> first];
}
void Swap(int &a, int &b)
{
a ^= b ^= a ^= b;
}
void Up(int poz)
{
while(poz > 1 && Dist[Heap[poz >> 1]] > Dist[Heap[poz]])
{
swap(Heap[poz >> 1], Heap[poz]);
swap(Pos[Heap[poz >> 1]], Pos[Heap[poz]]);
poz >>= 1;
}
}
void Down(int x)
{
int y = 0;
while(x != y)
{
y = x;
if(2 * y <= L && Dist[Heap[2 * y]] < Dist[Heap[x]])
x = 2 * y;
if(2 * y + 1 <= L && Dist[Heap[2 * y + 1]] < Dist[Heap[x]])
x = 2 * y + 1;
swap(Heap[x], Heap[y]);
swap(Pos[Heap[x]], Pos[Heap[y]]);
}
}
void Push(int x)
{
Heap[++ L] = x, Pos[x] = L;
Up(L);
}
int Pop()
{
int now = Heap[1];
swap(Heap[1], Heap[L]);
swap(Pos[Heap[1]], Pos[Heap[L]]);
Heap[L] = Pos[Heap[L]] = 0;
L --;
Down(1);
return now;
}
bool Dijkstra()
{
int i, node;
for(i = 1; i <= N; i++)
Dist[i] = inf;
Dist[S] = 0;
Push(S);
while(L)
{
int node = Pop();
for(vector<PII> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
if(Dist[it -> first] > Dist[node] + it -> second)
if(Capacity[node][it -> first] > CurrentFlow[node][it -> first])
{
Dist[it -> first] = Dist[node] + it -> second;
Father[it -> first] = node;
if(Pos[it -> first]) Up(Pos[it -> first]);
else Push(it -> first);
}
}
return Dist[D] != inf;
}
int main()
{
ifstream in("fmcm.in");
ofstream out("fmcm.out");
int i, j;
in >> N >> M >> S >> D;
for(i = 1; i <= M; i++)
{
in >> X >> Y >> C >> Z;
G[X].pb(mp(Y, Z));
G[Y].pb(mp(X, -Z));
Capacity[X][Y] = C;
}
BellmanFord();
Update();
Sum = Dist[D];
int ans = 0;
while(Dijkstra())
{
int minFlow = inf, node;
for(node = D; node != S; node = Father[node])
minFlow = min(minFlow, Capacity[Father[node]][node] - CurrentFlow[Father[node]][node]);
for(node = D; node != S; node = Father[node])
{
CurrentFlow[Father[node]][node] += minFlow;
CurrentFlow[node][Father[node]] -= minFlow;
}
Sum += Dist[D];
ans += Sum * minFlow;
Update();
}
out << ans;