Pagini recente » Cod sursa (job #317275) | Cod sursa (job #2264759) | Cod sursa (job #725694) | Cod sursa (job #2206826) | Cod sursa (job #680391)
Cod sursa(job #680391)
#include<cstdio>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#define infile "fmcm.in"
#define outfile "fmcm.out"
#define n_max 355
#define INF 1<<30
#define nxt *it
#define pb push_back
#define mkp make_pair
#define FOR(g) \
for(vector<int> ::iterator it = g.begin(); it!=g.end(); ++it)
using namespace std;
vector < int > v[n_max];
int Cost[n_max][n_max], C[n_max][n_max], F[n_max][n_max], Dist[n_max], T[n_max];
int poz[n_max], H[n_max], NN;
int N, M, Src, Sink;
int Sum;
void citeste()
{
freopen(infile,"r",stdin);
scanf("%d %d %d %d", &N, &M, &Src, &Sink);
int x, y, c, cost;
while(M--)
{
scanf("%d %d %d %d", &x, &y, &c, &cost);
v[x].pb(y);
v[y].pb(x);
Cost[x][y] = cost;
Cost[y][x] = -cost;
C[x][y] = c;
}
fclose(stdin);
}
void BellmanFord()
{
for(int i=1;i<=N;++i)
Dist[i] = INF;
Dist[Src] = 0;
int stop = 1;
for(int i=1;i<=N && stop; ++i)
{
stop = 0;
for(int nod=1; nod<=N; ++nod)
FOR(v[nod])
if(C[nod][nxt] > F[nod][nxt] && Dist[nod] + Cost[nod][nxt] < Dist[nxt])
{
stop = 1;
Dist[nxt] = Dist[nod] + Cost[nod][nxt];
}
}
Sum = Dist[Sink];
}
inline int pop()
{
int nmin = H[1];
poz[nmin] = 0;
H[1] = H[NN--];
poz[H[1]] = 1;
int k = 1, ls, rs, son;
while(1)
{
son = k;
ls = k<<1;
rs = k<<1 + 1;
if(ls <= NN && Dist[H[ls]] < Dist[H[son]])
son = ls;
if(rs <= NN && Dist[H[rs]] < Dist[H[son]])
son = rs;
if(son == k)
break;
swap(poz[H[son]], poz[H[k]]);
swap(H[son], H[k]);
k = son;
}
return nmin;
}
inline void push(int x)
{
int k;
if(poz[x])
k = poz[x];
else
{
H[++NN] = x;
poz[x] = NN;
k = NN;
}
while(k > 1 && Dist[H[k]] < Dist[H[k>>1]])
{
swap(poz[H[k]], poz[H[k>>1]]);
swap(H[k], H[k>>1]);
k >>= 1;
}
}
inline bool Dijkstra()
{
for(int i=1; i<=N; i++)
FOR(v[i])
if(Dist[i]!=INF && Dist[nxt]!=INF)
Cost[i][nxt] += Dist[i] - Dist[nxt];
for(int i=1;i<=N;i++)
{
Dist[i] = INF;
T[i] = poz[i] = 0;
}
Dist[Src] = 0;
push(Src);
while(NN)
{
int nod = pop();
FOR(v[nod])
if(C[nod][nxt] - F[nod][nxt] > 0 && Dist[nod] + Cost[nod][nxt] < Dist[nxt])
{
Dist[nxt] = Dist[nod] + Cost[nod][nxt];
push(nxt);
T[nxt] = nod;
}
}
return Dist[Sink] != INF ;
}
long long Flux()
{
long long sol = 0;
while(Dijkstra())
{
int fmin = INF;
for(int i = Sink; i != Src; i = T[i])
fmin = min(fmin, C[T[i]][i] - F[T[i]][i]);
for(int i = Sink; i != Src; i = T[i])
{
F[T[i]][i] += fmin;
F[i][T[i]] -= fmin;
}
Sum += Dist[Sink];
sol += Sum * fmin;
}
return sol;
}
void afiseaza()
{
freopen(outfile,"w",stdout);
printf("%lld\n",Flux());
fclose(stdout);
}
int main()
{
citeste();
BellmanFord();
afiseaza();
return 0;
}