Pagini recente » Cod sursa (job #91742) | Cod sursa (job #401847) | Cod sursa (job #233299) | Cod sursa (job #1255533) | Cod sursa (job #761144)
Cod sursa(job #761144)
#include<fstream>
#include<vector>
#include<queue>
using namespace std;
#define nmax 360
#define foreach(V) for(vector<int> :: iterator it = V.begin(); it != V.end(); it++)
#define ll long long
#define min(a,b) (a>b ? b : a)
const int inf = 1<<30;
ifstream fin("fmcm.in");
ofstream fout("fmcm.out");
int N, M, C[nmax][nmax];//capacitate
int TT[nmax], cost[nmax][nmax], dist[nmax], S, D, sum, drum ;
int F[nmax][nmax];
vector<int> G[nmax];
int H[nmax], P[nmax], L;
void push(int x)
{
int aux;
while(x/2 > 1 &&dist[H[x]] < dist[H[x/2]])
{
aux = H[x]; H[x] = H[x/2]; H[x/2] = aux;
P[H[x/2]]= x/2;
P[H[x]] = x;
x/=2;
}
}
void pop(int x)
{
int y = 0, aux = 0;
while(x != y)
{
y = x;
if(y * 2 <= L && dist[H[x]] > dist[H[y * 2]]) x = y * 2;
if(y * 2 + 1 <=L && dist[H[x]] > dist[H[y*2 + 1]] ) x = y * 2 + 1;
aux = H[x] ; H[x] = H[y] ; H[y] = aux;
P[H[x]] = x;
P[H[y]] = y;
}
}
void BellmanFord()
{
queue <int> q;
for(int i = 1; i <= N; i++)
dist[i] = inf;
dist[S] = 0;
q.push(S);
while( !q.empty() )
{
int nod = q.front();
q.pop();
foreach(G[nod])
{
int y = (*it);
if(dist[nod] + cost[nod][y] < dist[y] && C[nod][y] > 0)
{
dist[y] = cost[nod][y] + dist[nod];
q.push(y);
}
}
}
//for(int i = 1; i <= N ;i++)
// fout <<dist[i] <<" " ;
sum = dist[D];//costul cel mai bun de la sursa la destinatie
}
int Dijkstra()
{
//Fac transformarile astfel incat sa am doar costuri pozitive pe arcekle active (capcitate> flux)
for(int i = 1; i <= N ;i++)
foreach(G[i])
if(dist[i] != inf && dist[*it] != inf)
cost[i][*it] += dist[i] - dist[*it];
for(int i = 1; i <= N; i++)
{
dist[i] = inf;
TT[i] = -1;
H[i] = i;
P[i] = i;
}
dist[S] = 0 ;
H[1] = S; H[S] = 1;
P[1] = S; P[S] = 1;
L = N;
while(L>1 && dist[H[1]] !=inf)
{
int x = H[1];
foreach(G[x])
{
int v = *it;
if(C[x][v] - F[x][v] > 0 && dist[x] + cost[x][v] < dist[v])
{
dist[v] = dist[x] + cost[x][v];
TT[v] = H[1];
push(P[v]);
}
}
H[1] = H[L--];
P[H[1]] = 1;
if(L>1) pop(1);
}
//fout << dist[D] <<'\n';
if(dist[D] != inf)
{
int vmin = inf;
drum = 1;
for(int i = D; i != S; i = TT[i])
vmin = min(vmin, C[TT[i]][i] - F[TT[i]][i]);
for(int i = D; i != S; i = TT[i])
{
F[TT[i]][i] += vmin;
F[i][TT[i]] -= vmin;
}
// fout <<vmin <<'\n';
sum+=dist[D];
return vmin * sum;
}
return 0;
}
ll det_flux()
{
ll rez = 0;
drum = 1;
while(drum)
{
drum = 0;
rez += Dijkstra();
}
return rez;
}
void read()
{
int x, y, z, cap;
fin >>N>> M;
fin>> S>> D;
for(int i = 1; i <= M;i++)
{
fin >>x >> y>>cap>>z;
G[x].push_back(y);
G[y].push_back(x);
cost[x][y] = z;
cost[y][x] = -z;
C[x][y] = cap;
}
}
int main()
{
read();
BellmanFord();
fout << det_flux();
fin.close();
return 0;
}